为毛GCLocker Initiated GC导致CMS Final Remark时间很长呢

【为毛GCLocker Initiated GC导致CMS Final Remark时间很长呢】 感谢 @王四哥达家码 分享的问题。
使用JNI临界区的方式操作数组或者字符串时,为了防止GC过程中jarray或者jstring发生位移,而导致数组指针失效,需要保持它们在JVM Heap中的地址在JNI Critical过程中保持不变。于是JVM实现了GC_locker,用于JNI Critical内阻止其他GC的发生。
当GCLocker被激活且需要发生GC的时候(这里是否需要GC是各种GC发生时,调用GCLocker::check_active_before_gc()函数check并设置_needs_gc = true的),就会阻塞其他线程进入JNI临界区;并且在最后一个位于JNI临界区的线程退出临界区时,发起一次CGCause为_gc_locker的GC。这里解释了GCLocker Initiated GC发生的原委。
至于ReScan时间过长,我理解是CMS在执行collect时被block,而导致下次CMS发生时,需要Scan堆的范围过大引起的。当然如果其他人对此有异议,欢迎怼我,并分享之。
谢谢,上面的表述,在Hotspot VM中的实现,参考:
https://github.com/dmlloyd/openjdk/blob/jdk9/jdk9/hotspot/src/share/vm/gc/shared/gcLocker.cpp#L109
https://github.com/dmlloyd/openjdk/blob/jdk9/jdk9/hotspot/src/share/vm/gc/shared/gcLocker.cpp#L125
https://github.com/dmlloyd/openjdk/blob/jdk9/jdk9/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp#L422

■网友
好了,明白了,这事儿是在CMS和G1不可避免的。。。JVM Anatomy Park #9: JNI Critical and GC Locker
@ETIN @茶盒装 最后是这样,Paul说这个问题G1其实改善了很多,并不一定非要等Shenandoah。最后我看了一下,也测试了。在YG,在exit Critical region之后,它只是flag要做GCLocker Initiated GC,但是并不会马上做,还是会等到要做YG collection的时候做。这点好处已经非常大了。。。少了很多不必要的YG collection。
对于OG,Paul说G1还是会pin那个region的,不会block整个phase。现在起码代码道理上讲是这样,跑了12个小时也没有发生long pause。而且把这样可能逼我们migrate到G1了,因为即使一次普通final remark的pause也变成了三分之一,这个我们的P99.99 metrics一下就漂亮了(逃

■网友
试试CMSScavengeBeforeRemark


    推荐阅读