本文转自blog:
http://spaces.msn.com/songsun/
先说tuning,gc有两个指标,一个是frequentcy(以下称F),一个是duration(以下称D)。前者和程序产生garbage的速率和java heap大小有关,后者和java heap大小及gc thread数有关。依据应用程序的差异,F可能为30秒/次或者数小时/次不等,都是可接受的,而D则越短越好,因为它jvm让人感到pause的时刻。在应用程序和gc thread数给定的条件下,F和D是矛盾的,一个的减小意味着另一个的增大,因为F低了,说明heap size很大,而大的heap意味着gc要花费较多的时间,即D要增加,反之亦然。下面是几条准则:
1. 你应该设置gc thread数与系统的cpu个数一致,道理很简单,多了是无用的,少了是浪费cpu。
2. min heap size应该设置在java heap的谷值或略大的水平,谷值和峰值如果没有profiling工具,打开-verbose:gc做计算。
3. max heap size约设置为java heap峰值的10/7倍,也就是max heap size的70%约等于峰值。也可以更大些,2倍左右。一定要注意物理内存的多寡,不要大得被paging到硬盘上去了,那就得不偿失了。
4. 最后,稳定压倒一切,继续用-verbose:gc观测一段时间(有时甚者要多天),看看F和D是否可以保持在稳定的水平上。如果排出额外因素的影响还是波动太大,说明还需要进一步调节。
以上是一般过程,当然,你还应该参考所使用的jvm的document,注意其特征。
续trouble shooting
内存方面的trouble shooting主要就是解决OutOfMemory(以下简称OOM),导致OOM的原因总的来说有2种:第一是内存泄露,随着运行时间增加,内存逐渐吃紧,终于不治;第二是实际需要大于最大heap size,也就是说-Xmx太小了,需要调高(如果你上面的tuning做好了,就不会这样了)。直接原因就五花八门了,比如有的jvm,当在80%的cpu时间内,不能gc出2%的heap时,也发生OOM,还有一种可能是,你的heap实际使用并不大,free空间总数是充足的,但不巧的是free空间都是碎片而heap又不能compact,那么内存分配请求失败,发生OOM。
一般发生OOM时,jvm会导出heapdump,即使你对系统一无所知,只拥有一个heapdump就足以了。IBM alphaWorks上有一个HeapRoots工具可以用来分析heapdump(最好使用ibm的jre运行该工具,对于有些phd格式的堆,还用当使用svcdump.jar)。
假如你没有heapdump可用,那么需要检查系统是否禁止了heapdump,甚至有时需要手工使jvm产生heapdump(unix环境下,kill -3 pid,win32下,ctrl+break)。
一切就绪后,使用命令行
> java -Xbootclasspath/p:svcdump.jar -Xmx768M -jar HR207.jar -i heapdump.xxxx.phd
先说tuning,gc有两个指标,一个是frequentcy(以下称F),一个是duration(以下称D)。前者和程序产生garbage的速率和java heap大小有关,后者和java heap大小及gc thread数有关。依据应用程序的差异,F可能为30秒/次或者数小时/次不等,都是可接受的,而D则越短越好,因为它jvm让人感到pause的时刻。在应用程序和gc thread数给定的条件下,F和D是矛盾的,一个的减小意味着另一个的增大,因为F低了,说明heap size很大,而大的heap意味着gc要花费较多的时间,即D要增加,反之亦然。下面是几条准则:
1. 你应该设置gc thread数与系统的cpu个数一致,道理很简单,多了是无用的,少了是浪费cpu。
2. min heap size应该设置在java heap的谷值或略大的水平,谷值和峰值如果没有profiling工具,打开-verbose:gc做计算。
3. max heap size约设置为java heap峰值的10/7倍,也就是max heap size的70%约等于峰值。也可以更大些,2倍左右。一定要注意物理内存的多寡,不要大得被paging到硬盘上去了,那就得不偿失了。
4. 最后,稳定压倒一切,继续用-verbose:gc观测一段时间(有时甚者要多天),看看F和D是否可以保持在稳定的水平上。如果排出额外因素的影响还是波动太大,说明还需要进一步调节。
以上是一般过程,当然,你还应该参考所使用的jvm的document,注意其特征。
续trouble shooting
内存方面的trouble shooting主要就是解决OutOfMemory(以下简称OOM),导致OOM的原因总的来说有2种:第一是内存泄露,随着运行时间增加,内存逐渐吃紧,终于不治;第二是实际需要大于最大heap size,也就是说-Xmx太小了,需要调高(如果你上面的tuning做好了,就不会这样了)。直接原因就五花八门了,比如有的jvm,当在80%的cpu时间内,不能gc出2%的heap时,也发生OOM,还有一种可能是,你的heap实际使用并不大,free空间总数是充足的,但不巧的是free空间都是碎片而heap又不能compact,那么内存分配请求失败,发生OOM。
一般发生OOM时,jvm会导出heapdump,即使你对系统一无所知,只拥有一个heapdump就足以了。IBM alphaWorks上有一个HeapRoots工具可以用来分析heapdump(最好使用ibm的jre运行该工具,对于有些phd格式的堆,还用当使用svcdump.jar)。
假如你没有heapdump可用,那么需要检查系统是否禁止了heapdump,甚至有时需要手工使jvm产生heapdump(unix环境下,kill -3 pid,win32下,ctrl+break)。
一切就绪后,使用命令行
> java -Xbootclasspath/p:svcdump.jar -Xmx768M -jar HR207.jar -i heapdump.xxxx.phd
os 1-5
注意:如果heapdump文件本身很大,-Xmx768M需要增大;分析时尽量使用高配置的计算机,否则太慢,你会比较郁闷。
启动heaproots作分析,load完毕后:
* 输入p命令(help可以列出所有命令的注释)作预处理。
* 然后使用ot和ts分析对象和类所占空间的排序,默认列出前25个。
* 过程中过滤器很有用,com/foo为过滤则仅输出com.foo为前缀类型。
* 所占堆排名靠前的那些类别或对象,需要检查是否是内存泄露的结果或者是否有代码优化的余地。
* 如果对某对象感兴趣,使用i 0x<addr>命令深入追踪之。
注:一般发生OOM时,有的jvm在heapdump之前,会作一次gc,以利对堆的分析。
再注:以上的手段在实际中多次应用,有效率达99.9999%以上!
注意:如果heapdump文件本身很大,-Xmx768M需要增大;分析时尽量使用高配置的计算机,否则太慢,你会比较郁闷。
启动heaproots作分析,load完毕后:
* 输入p命令(help可以列出所有命令的注释)作预处理。
* 然后使用ot和ts分析对象和类所占空间的排序,默认列出前25个。
* 过程中过滤器很有用,com/foo为过滤则仅输出com.foo为前缀类型。
* 所占堆排名靠前的那些类别或对象,需要检查是否是内存泄露的结果或者是否有代码优化的余地。
* 如果对某对象感兴趣,使用i 0x<addr>命令深入追踪之。
注:一般发生OOM时,有的jvm在heapdump之前,会作一次gc,以利对堆的分析。
再注:以上的手段在实际中多次应用,有效率达99.9999%以上!
Heaproots下载链接
http://www.alphaworks.ibm.com/tech/heaproots/download