前言:
具体来讲:
Java整个堆大小设置,Xmx 和 Xms设置为老年代存活对象的3-4倍,即FullGC之后的老年代内存占用的3-4倍
永久代 PermSize和MaxPermSize设置为老年代存活对象的1.2-1.5倍。
年轻代Xmn的设置为老年代存活对象的1-1.5倍。
老年代的内存大小设置为老年代存活对象的2-3倍。
接下来基于我自己公司生产的两台负载服务器的一台进行实验.
第一步:采用默认设置新生代和老年代的方式获取gc的总耗时时间.
原有设置是堆内存1024m 新生代采取默认值
# gc是查看gc运行情况. 18204是程序的pid(可以通过ps aux|grep 程序name获取 ) 5000是5秒执行一次 共执行5次.
jstat -gc 18204 5000 5
下面的YGCT代表年轻代执行的秒数,YGC是次数. FGCT是老年代执行的秒数, FGC是次数.
一次 gc 年轻代垃圾回收每次花费时间 YGCT*1000/YGC = 2.425s*1000/191 = 12.69ms
一次 gc 老年代垃圾回收每次花费时间。FGCT*1000/FGC = 1.113s*1000/4= 278 ms 0.278s
总gc耗时 290.69ms
第二步:推算应该优化的老年代值.
通过执行jmap -heap 18204 来看的当前的堆内存情况(也可以根据GC日志来看)
发现老年代默认是683m 使用的是270m 因此按照整个堆大小是老年代(FullGC)之后的3-4倍计算的话 设置新生代256m 老年带768m 差不多3倍.
此时设置堆内存 1024m 新生代256m 老年代为堆内存大小减去新生代大小算出为768m
再次获取gc
# gc是查看gc运行情况. 18204是程序的pid(可以通过ps aux|grep 程序name获取 ) 5000是5秒执行一次 共执行5次.
jstat -gc 18204 5000 5
一次 gc 年轻代垃圾回收每次花费时间 0.777s*1000/59 = 13.169ms 慢了1ms左右
一次 gc 老年代垃圾回收每次花费时间。0.703*1000/4= 175.75ms 0.175s 175.75 快了一半时间.
总gc耗时 188.91ms
新生代gc变慢 老年代gc变快 总体提升了290.69ms-188.91ms=101.78ms 效果显而易见
第三步:增加堆内存和新生代内存大小.再次观察总耗时
设置堆内存 2048m 新生代512m 老年代 1536m
再次获取gc
# gc是查看gc运行情况. 18204是程序的pid(可以通过ps aux|grep 程序name获取 ) 5000是5秒执行一次 共执行5次.
jstat -gc 18204 5000 5
一次 gc 年轻代垃圾回收每次花费时间 0.367s*1000/25 = 14.68ms 又慢了1ms左右
一次 gc 老年代垃圾回收每次花费时间。0.633*1000/4= 158.25ms 0.15825s 158.25 快了17ms时间.
总结:
可见 此时该程序从堆内存设置为1g再到2g 其实提升并不是多大…最主要的设置是加上了新生代内存设定,而不是采用默认值...有上面的结果可以知道基本上1g就可以满足程序使用要求了. 当然内存足够可以继续加.