java 对象分配过程

发布时间 2023-04-14 12:19:00作者: HANGYCHN
  • 对象优先分配到新生代的 伊甸园区(Eden)
    • 大多数情况下,新对象最初放在 Eden,当 Eden 内存不足时发生minor GC(轻GC)
    • minor GC 清理的不仅是 Eden 而是整个新生代(Eden 和两个 幸存区),即当 Eden 或 幸存区 内存不足时都会触发
    • 幸存区有两个区,s0(from)和s1(to),每次 minor GC 会把 Eden 和 其中一个幸存区存活的对象(顺序)放到另一个幸存区
    • 为什么要两个幸存区?根据 minor GC 的工作原理可知,是为了保证幸存区没有磁盘碎片,如果只有一个幸存区,回收垃圾之后内存肯定不是连续的
  • 大对象会直接进入老年代
    • 大对象就是需要大量连续的内存空间的对象,比如字符串(每个字符都是一个 char 对象)、数组等
    • 为什么大对象直接放入老年代?专业解释的术语是因为分配担保。我的理解是比如字符串,要吗全部回收,要吗不回收。因为不可能回收其中的某一个字符,所以回收的效果并不大,反而还要不停的在 Eden、幸存区、老年代中复制,影响性能
  • 长期存活的对象将进入老年代
    • 多次 minor GC 之后幸存区会不足,达到回收阈值后还存活的放入老年代中
    • 阈值:虚拟机会给每个对象一个年龄计数器,每发生一次 minor GC 如果对象还存活年龄+1。阈值和垃圾回收器相关,并不是所有的默认阈值都是 15。可以通过 -XX:MaxTenuringThreshold 来设置阈值