当 Eden 空间年轻代满时,会触发 Minor GC。并且在minor GC过程中,Eden中的非自由对象和一个源Survivor空间将被复制到另一个目标Survivor空间。
我的问题是,如果目标 Survivor 空间已满,minor GC 怎么处理?
当 Eden 空间年轻代满时,会触发 Minor GC。并且在minor GC过程中,Eden中的非自由对象和一个源Survivor空间将被复制到另一个目标Survivor空间。
我的问题是,如果目标 Survivor 空间已满,minor GC 怎么处理?
年轻代有 3 个段 Eden Space,Survivor1 和 Survivor2。这些只是年轻一代的逻辑划分。所以对象会从 Eden Space 复制到 Survivor1,然后再复制到 Survivor2。
所以一般的minorcollection意味着collection发生在年轻代。如果年轻代已满,则对象将被复制到老年代。
同样,收集是次要还是主要取决于多个因素,其中之一是年轻一代的空间可用性。因此,如果年轻代中有足够的空间用于对象分配,那么它将是次要收集。但是如果 YG 中没有足够的可用空间,那么同一个集合可以变成主要的。
JVM规范也没有谈论垃圾收集。所以它留给JVM实现者有自己的策略。
如果无法进行/完成次要收集,则执行主要/完整收集。这通常是使用标记-扫描-压缩算法而不是复制算法来完成的……这也是完整收集成本高昂的原因之一。
但最终(如果你继续填满堆)一个完整的集合将无法回收足够的空间来继续,并且会抛出一个 OOME。(或者如果你使用-XX:+UseGCOverheadLimit
,当花费在 GC 中的时间百分比超过指定阈值时,将抛出 OOME。)