首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 互联网 >

DisableExplicitGC跟Direct ByteBuffer

2012-12-26 
DisableExplicitGC和Direct ByteBuffer?? ? 如果在JVM 的配置中添加了DisableExplicitGC这个配置,但是同时

DisableExplicitGC和Direct ByteBuffer

?

? ? 如果在JVM 的配置中添加了DisableExplicitGC这个配置,但是同时应用中有用到了Direct ByteBuffer(例如用到了NIO框架mina),此时会由于内存问题导致OOM,之前有所了解,但是没有仔细看过,最近同事排查了一个这种问题,然后决定扫盲一下,期间重点参照撒迦(不得不佩服他在JVM上的权威?)的这篇Topic(http://hllvm.group.iteye.com/group/topic/27945)。

????(1)DisableExplicitGC这个配置的作用是啥?

-XX:+DisableExplicitGC标志自动将System.gc()调用转换成一个空操作,就是应用中调用System.gc()会变成一个空操作。最主要的原因是为了防止某些手贱的同学在代码里到处写System.gc()的调用而干扰了程序的正常运行吧。有些应用程序本来可能正常跑一天也不会出一次full?GC,但就是因为有人在代码里调用了System.gc()而不得不间歇性被暂停。

????(2)应用中调用System.gc()会有啥影响?

在Oracle/Sun?JDK这个具体实现上,System.gc()的默认效果是引发一次stop-the-world的full?GC,对整个GC堆做收集,对于应用的影响可想而知。

????(3)DisableExplicitGC这个设置了会有啥坑?

其中一种情况是下述三个条件同时满足时会发生的:?

1、应用本身在GC堆内的对象行为良好,正常情况下很久都不发生full?GC;?

2、应用大量使用了NIO的direct?memory,经常、反复的申请DirectByteBuffer?

3、使用了-XX:+DisableExplicitGC?

此时有可能会抛出这个异常:java.lang.OutOfMemoryError:?Direct?buffer?memory??

????(4)Direct ?ByteBuffer有啥值得注意的地方?

1、DirectByteBuffer没有finalizer,它的native?memory的清理工作是通过sun.misc.Cleaner自动完成的。?

2、sun.misc.Cleaner是一种基于PhantomReference的清理工具,比普通的finalizer轻量些。

做full?GC的话会对old?gen做reference?processing,进而能触发Cleaner对已死的DirectByteBuffer对象做清理工作。

而如果很长一段时间里没做过GC或者只做了young?GC的话则不会在old?gen触发Cleaner的工作,

那么就可能让本来已经死了的、但已经晋升到old?gen的DirectByteBuffer关联的native?memory得不到及时释放。

3、为DirectByteBuffer分配空间过程中会显式调用System.gc(),以期通过full?GC来强迫已经无用的DirectByteBuffer对象释放掉它们关联的native?memory:?

?

这几个实现特征使得Oracle/Sun?JDK?6依赖于System.gc()触发GC来保证DirectByteMemory的清理工作能及时完成。

如果打开了-XX:+DisableExplicitGC,清理工作就可能得不到及时完成,于是就有机会见到direct?memory的OOM。

????(5)使用了Direct??ByteBuffer应该咋处理?

如果你在使用Oracle/Sun?JDK?6,应用里有任何地方用了direct?memory,那么使用-XX:+DisableExplicitGC要小心。

如果用了该参数而且遇到direct?memory的OOM,可以尝试去掉该参数看是否能避开这种OOM。

如果担心System.gc()调用造成full?GC频繁,可以尝试下面提到?-XX:+ExplicitGCInvokesConcurrent?参数?

(?-XX:+ExplicitGCInvokesConcurrent ?System.gc()和应用程序并发执行,就是不stop-the-world)

-XX:+ExplicitGCInvokesConcurrent?或?-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses?

这两个参数也是用来改变System.gc()的默认行为用的;不同的是这两个参数只能配合CMS使用(-XX:+UseConcMarkSweepGC),

而且System.gc()还是会触发GC的,只不过不是触发一个完全stop-the-world的full?GC,而是一次并发GC周期。?

CMS?GC周期中也会做reference?processing。

所以如果用这两个参数的其中一个,而不是用-XX:+DisableExplicitGC的话,就避开了由full?GC带来的长GC?pause,

同时NIO?direct?memory的OOM也不会那么容易发生。

????(6)MaxDirectMemorySize?与?NIO?direct?memory?的默认上限?

-XX:MaxDirectMemorySize?是用来配置NIO?direct?memory上限用的VM参数。

?MaxDirectMemorySize没显式配置的时候,NIO?direct?memory可申请的空间的上限就是-Xmx减去一个survivor?space的预留大小。?

????(7)HeapDump位置问题

-XX:+HeapDumpBeforeFullGC、-XX:+HeapDumpAfterFullGC、-XX:+HeapDumpOnOutOfMemoryError?这几个参数可以在不同条件下做出HPROF格式的heap?dump。

如果不想费神去摸索到底各种环境被配置成什么样、“working?directory”到底在哪里的话,就在VM启动参数里加上?-XX:HeapDumpPath=一个绝对路径?吧。这样,自动做出的heap?dump就会被存到指定的目录里去。?


?










热点排行