Java GC 分配担保时为何需要检查老年代最大可用的连续空间?

看到一段话:

在发生Minor GC之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果这个条件成立,那么Minor GC可以确保是安全的。如果不成立,则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。如果允许,那么会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小

为什么是要连续的空间大于新生代所有对象总空间?我怎么觉得是老年代连续的空间大于新生代的最大对象需要的空间,而不是“新生代所有对象总空间”? 所有的新生代对象必须要放在连续的空间上吗?

而这句话“继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小”,这个平均大小是指单个对象的平均大小还是所有对象之和的平均大小?

阅读 4.3k
2 个回答

这句话出自<<深入理解Java虚拟机>>第二版,你需要看完这本书的垃圾收集算法,才知道为什么.简单的说你错在哪呢,如果新生代所有的对象都在链上不可回收呢?

确定哪些对象可以回收通常有两种算法,一种是引用计数,一种是可达性分析算法.HotSpot采用的就是第二种.第二种会通过一些称为GC Root的对象.可作为GC Roots的对象包括下面几种:

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象。
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象。
  • 本地方法栈中JNI(即一般说的Native方法)引用的对象

这些引用会形成一条链,凡是在链上的说明还在使用,不可回收.

问题一,既然是担保,则要保证100%成功。如果老年代有很多空闲区,但都非常小,小到不足以分配一个对象,那么及时老年代有很大空间,也是做不了担保的,必须是连续。此外,新生代的对象可能会在某一次集体提升到老年代,为了担保,老年代空闲必须大于整个年轻代大小。
综合,老年代最大连续空闲空间需大于年轻代总空间。

问题二,所有提升到老年代对象大小的总和。这里的平均只是平均了每次ygc时,提升的年轻代对象大小总和。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题