java中,描述一下什么情况下,对象会从年轻代进入老年代?

2021-03-07 22:48发布

4条回答

当对象在 Survivor 区躲过一次 GC 后,其年龄就会+1。默认情况下年龄到达 15 的对象会被移到老生代中。分代收集法是目前大部分 JVM 所采用的方法,其核心思想是根据对象存活的不同生命周期将内存 划分为不同的域,一般情况下将 GC 堆划分为老生代(Tenured/Old Generation)和新生代(Young  Generation)。老生代的特点是每次垃圾回收时只有少量对象需要被回收,新生代的特点是每次垃 圾回收时都有大量垃圾需要被回收,因此可以根据不同区域选择不同的算法。那什么情况下对象会从新生代进入到老年代呢?

目前大部分的JVM的GC对于新生代都采用的是复制算法,因为新生代中每次垃圾回收都要 回收大部分对象,即要复制的操作比较少,但通常并不是按照 1:1 来划分新生代。一般将新生代 划分为一块较大的 Eden 空间和两个较小的 Survivor 空间(From Space, To Space),每次使用 Eden 空间和其中的一块 Survivor 空间,当进行回收时,将该两块空间中还存活的对象复制到另 一块 Survivor 空间中。

而老年代因为每次只回收一小部分的对象,所以采用的是标记-复制算法。

对象的内存分配主要在新生代的 Eden Space 和 Survivor Space 的 From Space(Survivor 目 前存放对象的那一块),少数情况会直接分配到老生代。当新生代的 Eden Space 和 From Space 空间不足时就会发生一次 GC,进行 GC 后,Eden  Space 和 From Space 区的存活对象会被挪到 To Space,然后将 Eden Space 和 From  Space 进行清理。如果 To Space 无法足够存储某个对象,则将这个对象存储到老生代。 在进行 GC 后,使用的便是 Eden Space 和 To Space 了,如此反复循环。


以上是我理解的新生代和老年代的转换。


顺带提一嘴,在JDK1.8之后,将之前的“永久代”改为“元空间”了,这两者我觉得其实就是对方法区的一种实现。后者也弥补了前者的一些缺点,这里就不提了。

一周热门 更多>