在系列的最后,简单谈谈一些会有坑的JVM参数配置,以避免大家再多次踩坑
-XX:+DisableExplicitGC
很多的JVM标准配置中都有该选项,那么它究竟是干嘛的?
它会让System.gc()变成一次空调用,并不会真的发生一次Full Gc。除此以外,它还能避免第三方库定时引发的Full Gc(没错,说的就是RMI机制),看来很美好,对不对?
但有一种情况:应用本身GC正常,很久都不会Full Gc,但堆外内存增长很快,并且JVM启用了-XX:+DisableExplicitGC。你就会发现:应用运行一段时间后,就会崩溃,出现OOM。
原因就是就在于堆外内存只能在Old Gc或Full Gc时才会被释放,但当应用长期不会Full Gc及System.gc()被禁止,而堆外内存增长过快时就会发生上述的OOM(内存溢出)
总结:一般情况下直接开启该选项,如你的应用涉及到堆外内存,例如:JNI、NIO等,请改用-XX:+ExplicitGCInvokesConcurrent
-XX:+ExplicitGCInvokesConcurrent
该参数与-XX:+DisableExplicitGC一样,用来出发System.gc()。但不同的是,它不会触发一个完全停止的Full Gc,而是触发一个CMS的GC。所以它必须配套-XX:+UseConcMarkSweepGC一起使用(CMS的解释请看上文)
-XX:MaxDirectMemorySize
该参数用来设置堆外内存大小,未设置的情况下,其默认大小为:-Xmx减去S0区
-XX:+HeapDumpOnOutOfMemoryError
该参数表示在内存溢出时生成内存快照,与参数:-XX:HeapDumpPath=绝对路径 配合使用,直接配置一个绝对路径,当发生内存溢出时,直接在对应路径中生成内存快照。
看到这,估计很多人都会困惑,什么是堆外内存?
Java堆(-Xmx+-XX:MaxPermSize)之外,引用的内存,均成为堆外内存(vm本身在运行过程中分配的内存,codecache,jni里分配的内存,DirectByteBuffer分配的内存等)
引用堆外内存的对象本身都很小,但其引用的堆外内存可能非常巨大,因此通常称为冰山对象。