关于 JVM 参数中 ExplicitGCInvokesConcurrent的用途
2014-10-27 11:57
423 查看
网上看到有很多人在讨论 ExplicitGCInvokesConcurrent参数的用途。google了一下,半天都没找到 ExplicitGCInvokesConcurrent究竟为何物,到是发现了 ExplicitGCInvokesConcurrent出现的场景:
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 (这个关系让我一直疑问很久,究竟为什么要用ExplicitGCInvokesConcurrent参数来替代DisableExplicitGC,网上的发部分言论都在这么说,但是没有人清楚明白的说明清楚为什么! 而这才是最重要的),当然,是要在使用CMS做full GC的时候,才能使用这个参数
但是,到此,我还是不清楚ExplicitGCInvokesConcurrent的好处在哪,为什么可以替代DisableExplicitGC ,继续寻找后,发现了这篇文章:
http://breezylee.iteye.com/blog/2043056
里面有这么一段话:
3、-XX:+ExplicitGCInvokesConcurrent 或 -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses
C++代码
跟上面的第一个例子的-XX:+DisableExplicitGC一样,这两个参数也是用来改变System.gc()的默认行为用的;不同的 是这两个参数只能配合CMS使用(-XX:+UseConcMarkSweepGC),而且System.gc()还是会触发GC的,只不过不是触发一个 完全stop-the-world的full GC,而是一次并发GC周期(注:一次并发周期其实就是在CMS下的一次gc,CMS只能用在full gc 中,所以,也是一次full
gc 只不过效率比较高罢了)。
CMS GC周期中也会做reference processing。所以如果用这两个参数的其中一个,而不是用-XX:+DisableExplicitGC的话,就避开了由full GC带来的长GC pause,同时NIO direct memory的OOM也不会那么容易发生。
总结:到此,我们至少可以明白两个问题:
1. ExplicitGCInvokesConcurrent用途的由来。
2. ExplicitGCInvokesConcurrent本身的功能:其实,也是触发full gc 只不过在CMS在full gc 效率比较高。
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 (这个关系让我一直疑问很久,究竟为什么要用ExplicitGCInvokesConcurrent参数来替代DisableExplicitGC,网上的发部分言论都在这么说,但是没有人清楚明白的说明清楚为什么! 而这才是最重要的),当然,是要在使用CMS做full GC的时候,才能使用这个参数
但是,到此,我还是不清楚ExplicitGCInvokesConcurrent的好处在哪,为什么可以替代DisableExplicitGC ,继续寻找后,发现了这篇文章:
http://breezylee.iteye.com/blog/2043056
里面有这么一段话:
3、-XX:+ExplicitGCInvokesConcurrent 或 -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses
C++代码
跟上面的第一个例子的-XX:+DisableExplicitGC一样,这两个参数也是用来改变System.gc()的默认行为用的;不同的 是这两个参数只能配合CMS使用(-XX:+UseConcMarkSweepGC),而且System.gc()还是会触发GC的,只不过不是触发一个 完全stop-the-world的full GC,而是一次并发GC周期(注:一次并发周期其实就是在CMS下的一次gc,CMS只能用在full gc 中,所以,也是一次full
gc 只不过效率比较高罢了)。
CMS GC周期中也会做reference processing。所以如果用这两个参数的其中一个,而不是用-XX:+DisableExplicitGC的话,就避开了由full GC带来的长GC pause,同时NIO direct memory的OOM也不会那么容易发生。
总结:到此,我们至少可以明白两个问题:
1. ExplicitGCInvokesConcurrent用途的由来。
2. ExplicitGCInvokesConcurrent本身的功能:其实,也是触发full gc 只不过在CMS在full gc 效率比较高。
相关文章推荐
- 你假笨JVM参数 - 006 ExplicitGCInvokesConcurrent
- java nio 和 jvm 虚拟机参数的 XX:+DisableExplicitGC 的潜规则
- 关于在galssfish中配置jvm参数和gc日志的方法
- 关于JVM参数设置
- 关于JVM GC
- jvm__垃圾收集器介绍,GC 配置参数,回收器选择示例
- JVM启动参数之 -verbose:gc
- jvm GC 参数设置
- JVM gc参数设置与分析
- JVM 垃圾收集器及GC参数
- java jvm GC 参数设置
- JVM性能参数调优实践,不会执行Full GC,网站无停滞
- 毕设翻译——关于JVM的GC机制的比较
- JVM实用参数(八)GC日志
- 关于JVM的GC机制
- JVM GC参数配置说明
- JVM性能参数调优实践,不会执行Full GC,网站无停滞
- 转两篇关于JVM参数调优
- JVM GC 设置参数说明
- 关于JVM中参数问题 JVM系列三:JVM参数设置、分析