周期性Full GC的解决

                      周期性Full GC的解决

目录

背景

原因

参数说明


背景


线上应用的垃圾收集出现定时Full GC的异常现象。
1) 每隔10小时触发一次Full GC;
2) 每次Full GC持续时间约为2~3秒;
3) 与环境无关,线上环境、测试环境都会出现此问题;
 

原因

1. 很多NIO框架,比如netty会有很多内存映射的代码(memory map),而mmap的内存分配至不会在用Eden区或者old区的,是属于堆外分配,因此,这些框架中会手动调用system.gc来回收mmap分配的空间。(system.gc触发的是full gc,只有full gc时才会回收mmap分配的内存)。

2. 因为NIO框架频繁的调用full gc 会严重影响性能,因此,有人加上了这个参数:-XX:+DisableExplicitGC ,用来禁止system.gc对gc的触发。加上后system.gc()将不会触发gc。

3. 但是,如果完全不允许手动调用gc,

* 使用了NIO或者NIO框架(Mina/Netty)
* 使用了DirectByteBuffer分配字节缓冲区
* 使用了MappedByteBuffer做内存映射

以上情况下的堆外内存又无法回收,所以,才提到了用ExplicitGCInvokesConcurrent参数来替代DisableExplicitGC。

参数说明

参数:-XX:ExplicitGCInvokesConcurrent
含义:
Enables invoking of concurrent GC by using the System.gc() request.
This option is disabled by default and can be enabled only together with the -XX:+UseConcMarkSweepGC option.
System.gc()是正常FULL GC,在STW打开此参数后,在做System.gc()时会做background模式CMS GC(-XX:+UseConcMarkSweepGC),即并行FULL GC,可提高FULL GC效率。也就是说System.gc()还是会触发GC的,只不过不是触发一个 完全stop-the-world的full GC,而是一次并发GC周期(注:一次并发周期其实就是在CMS下的一次gc,CMS只能用在full gc 中,所以,也是一次full gc 只不过效率比较高罢了)
默认值:


注意:该参数在允许systemGC且使用CMS GC时有效。
 

猜你喜欢

转载自blog.csdn.net/xiao__jia__jia/article/details/104515179