GC悲观策略
Minor GC:只回收年轻代的垃圾。
Full GC:回收包括年轻代老年代永久代在内的java堆空间的垃圾。
GC悲观策略:在Minor GC中,根据年轻代平均晋升大小、年轻代占用空间、老年代空闲空间来判断是否进行一次Full GC。
0x01 为什么需要悲观策略?
通常情况下MinorGC的时候会将无法存放在suvivor的对象晋升到老年代中去,如果老年代空间无法存放下这些对象会触发一次FullGC,而FullGC中又会对年轻代进行一次MinorGC。因此在这种情况下,一次MinorGC会引发对年轻代的两次回收,悲观策略就是在尽量避免这种情况的发生。
0x02 Parallel GC的悲观策略
PSScavenge是Parallel的年轻代垃圾收集器。
bool PSScavenge::invoke() {
// 在年轻代收集失败的时候判断是否进行一次fullgc
const bool scavenge_done = PSScavenge::invoke_no_policy();
const bool need_full_gc = !scavenge_done ||
policy->should_full_GC(heap->old_gen()->free_in_bytes());
...
if (need_full_gc) {
...
if (UseParallelOldGC) {
full_gc_done = PSParallelCompact::invoke_no_policy(clear_all_softrefs);
} else {
full_gc_done = PSMarkSweep::invoke_no_policy(clear_all_softrefs);
}
}
return full_gc_done;
}
bool PSScavenge::invoke_no_policy() {
...
if (!should_attempt_scavenge()) {
return false;
}
...
}
bool PSScavenge::should_attempt_scavenge() {
...
size_t avg_promoted = (size_t) policy->padded_average_promoted_in_bytes();
size_t promotion_estimate = MIN2(avg_promoted, young_gen->used_in_bytes());
bool result = promotion_estimate < old_gen->free_in_bytes();
return result;
}
should_attempt_scavenge中的代码是取出年轻代的平均晋升大小,和当前年轻代的使用空间取最小值,如果这个最小值大于老年代剩余空间,则放弃当前的MinorGC进行一次FullGC。