`
songbin0201
  • 浏览: 319734 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

一次jvm内存调优的过程

 
阅读更多
继上次的内存调优分析后(参考[url] http://dmouse.iteye.com/blog/1264118[/url]),gc导致服务器不稳定的情况依然存在,以下记录了后续的调优和分析过程

目前线上有较多的 "Unloading class sun.reflect.GeneratedSerializationConstructorAccessor"、“promotion failed”、“concurrent mode failure”的错误、
关于这三个错误产生的原因,可以参考如下文章
http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html
http://blogs.oracle.com/jonthecollector/entry/when_the_sum_of_the
http://blogs.oracle.com/jonthecollector/entry/what_the_heck_s_a

综上所述,原因大概概括如下:
1、tenured的预留空间太小
2、young的一次回收的内存空间太大,以致于tenured无法一次分配连续的内存空间来满足需求
3、tenured的空闲内存空间不连续,碎片较多

目前线上系统虽然采用了较多的tenured的空间预留、采用了tenured的内存空间压缩,但仍然不定期的会出现较多的上述三种error,怀疑和设置空间压缩的参数有关
-XX:CMSFullGCsBeforeCompaction=0
这个参数,指定进行多少次fullGC之后,进行tenured的内存空间压缩,对 0 的理解认为是每次都会,建议设置为1进行管产
-XX:CMSFullGCsBeforeCompaction=1

目前每台服务器的上述三种error记录数如下
                         "Unloading class" "promotion failed" "concurrent mode failure"
50----------------------- 2233------------------------8-----------------------------------40
51 -----------------------2544------------------------15----------------------------------62
61_CPS----------------2698------------------------21---------------------------------31
61_CPS2---------------2573-----------------------17---------------------------------40
62_CPS----------------4815------------------------33---------------------------------47
62_CPS2--------------3608------------------------29---------------------------------183



分析内存回收日志,调整了-XX:CMSFullGCsBeforeCompaction=1参数后,回收稳定,无新增的 "Unloading class sun.reflect.GeneratedSerializationConstructorAccessor"、“promotion failed”、“concurrent mode failure”的错误



在JDK 6的HotSpot VM中,Oracle/Sun有官方支持的GC只有CMS比较特殊:其它几种GC的每个周期都是完全stop-the-world的;而CMS的每个并发GC周期则有两个stop-the-world阶段——initial mark与final re-mark,其它阶段是与应用程序一起并发执行的。


所以可以通过监控"initial-mark" 和 ‘remark’ 的时间,来反映因为gc导致的程序中断问题

-Xms3g -Xmx3g -Xmn1g -XX:PermSize=128M -XX:+PrintGCDetails -XX:+UseParNewGC -XX:ParallelGCThreads=8 -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=30 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=1 


按照目前配置,线上环境jvm垃圾回收效率提升,线程中断情况和中断时间明显减少
-Xms3g -Xmx3g -Xmn1g (堆最大内存 堆最小内存 新生代最大内存)
1、建议按照系统环境尽量设置合理的值
2、建议最大内存和最小内存尽量保持一致;jvm会动态分配内存,为了减少内存临时吃紧造成的重新分配开销,提高内存分配的稳定性;-Xms和-Xmx 默认为物理内存的1/64
3、建议尽量将新生代内存设置为较符合系统的值,避免过小的设置;新生代内存 = eden+ 2 survivor space;Sun官方推荐配置为整个堆的3/8

-XX:PermSize=128M (永久带内存大小)
1、存放编译后class对象的地方,默认物理内存的1/64,建议按照系统实际情况设置

-XX:+PrintGCDetails (打印gc详细信息)
形式诸如
[GC [ParNew: 839977K->1563K(943744K), 0.0048690 secs] 994555K->156183K(3040896K), 0.0052340 secs] [Times: user=0.02 sys=0.01, real=0.01 secs]

[GC [1 CMS-initial-mark: 629255K(2097152K)] 631951K(3040896K), 0.0066920 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[CMS-concurrent-mark: 1.385/1.385 secs] [Times: user=4.80 sys=0.29, real=1.38 secs]
[CMS-concurrent-preclean: 0.008/0.008 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
[GC [ParNew: 840863K->2737K(943744K), 0.0079350 secs] 1470119K->632187K(3040896K), 0.0084240 secs] [Times: user=0.03 sys=0.01, real=
0.01 secs]
[CMS-concurrent-abortable-preclean: 0.646/1.471 secs] [Times: user=2.48 sys=0.27, real=1.47 secs]
[GC[YG occupancy: 424421 K (943744 K)][Rescan (parallel) , 0.0519000 secs][weak refs processing, 0.0017730 secs] [1 CMS-remark: 6294
50K(2097152K)] 1053871K(3040896K), 0.0538830 secs] [Times: user=0.32 sys=0.01, real=0.05 secs]
[CMS-concurrent-sweep: 0.971/0.971 secs] [Times: user=2.06 sys=0.19, real=0.97 secs]
[CMS-concurrent-reset: 0.012/0.012 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]

具体内容解释详见 http://blogs.oracle.com/poonam/entry/understanding_cms_gc_logs

-XX:+UseParNewGC -XX:ParallelGCThreads=8 -XX:+UseConcMarkSweepGC (年轻代并行回收 收集器并行8个线程 年老代并发回收)
1、建议年轻代使用并行回收,同时按照操作系统processer的个数设置并行线程数,理论上<=操作系统processer个数
2、建议年老代使用并发回收,并发回收以降低中断次数,减少中断时间为目标,适用于对系统响应时间有较高要求的服务

-XX:CMSInitiatingOccupancyFraction=30 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=1
对年老代并发回收的参数优化
1、 -XX:CMSInitiatingOccupancyFraction=30
预留足够的空间给young gc,防止从young gc 过来一个较大的内存块,而年老代无足够预留空间,无法提供内存快用于回收后的分配,引起强制的full gc,造成较长时间的线程中断
2、-XX:+UseCMSCompactAtFullCollection
设置在FULL GC的时候, 对年老代的压缩;CMS是不会移动内存的, 因此, 这个非常容易产生碎片, 导致内存不够用, 因此, 内存的压缩这个时候就会被启用。 增加这个参数是个好习惯。可能会影响性能,但是可以消除碎片
3、 -XX:CMSFullGCsBeforeCompaction=1
设置多少次full gc后进行内存压缩,由于并发收集器不对内存空间进行压缩,整理,所以运行一段时间以后会产生"碎片",使得运行效率降低.此值设置运行多少次GC以后对内存空间进行压缩,整理。
分享到:
评论
1 楼 364902709 2012-10-23  
  我杯具的也要调这玩意了。。。

相关推荐

Global site tag (gtag.js) - Google Analytics