GC的两种类型
1. 新生代GC(Minor GC):指的是新生代中发生的垃圾回收,因为新生代中的对象创建和销毁都比较快,频繁,所以新生代的Minor GC发生很频繁,如果新生代中出现了FULL GC,一般是由于内存担保失败(新生代的存活的对象无法移动到老年代中)导致的
2. 老年代GC(Major GC/FULL GC):指的是老年代中发生的垃圾回收,一般伴随着一次Minor GC,而且FULL GC比Minor GC慢10倍以上
如何去调优
根据java Performance里面的内存设置策略:
具体来说:
1. 整个java堆的大小设置为full gc后老年代使用的内存空间大小的3-4倍
2. 永久代内存空间大小设置为1.2-1.5倍full GC后永久代使用的空间大小
3. 新生代大小设置为full GC后1-1.5倍老年代使用的内存空间大小
4. 老年代大小设置为full GC后2-3倍老年代使用的内存空间大小
note:
1. sun官方建议新生代占有java堆大小为3/8左右
2. java 堆 = 新生代+老年代 ,永久代的内存大小不算到java堆中
如果去确定full gc后老年代使用空间?
1. 观察gc日志,找出多次FULL GC后,老年代使用内存情况,取平均值
2. 借助工具,强制触发 FULL GC
强制触发:
使用jmap工具可触发FullGC
jmap -dump:live,format=b,file=heap.bin <pid> 将当前的存活对象dump到文件,此时会触发FullGC
jmap -histo:live <pid> 打印每个class的实例数目,内存占用,类全名信息.live子参数加上后,只统计活的对象数量. 此时会触发FullGC
后面借助jmap -heap <pid> 查看内存使用情况(建议查gc日志更准确),找出老年代大小进行调优
总结:
在内存相对紧张的情况下,可以按照上述的方式来进行内存的调优, 找到一个在GC频率和GC耗时上都可接受的一个内存设置,可以用较小的内存满足当前的服务需要
但当内存相对宽裕的时候,可以相对给服务多增加一点内存,可以减少GC的频率,GC的耗时相应会增加一些。 一般要求低延时的可以考虑多设置一点内存, 对延时要求不高的,可以按照上述方式设置较小内存。
实践开始,入手一个gc日志
Full GC
[PSYoungGen: 34816K->34335K(68608K)]
[ParOldGen: 204692K->204692K(204800K)] 239508K->239028K(273408K)
[PSPermGen: 17992K->17992K(21504K)], 0.5403820 secs]
[Times: user=5.01 sys=0.02, real=0.54 secs]
可以设置:
-Xms:613M
-Xmx:820M
-XX:PerSize=27M
-XX:MaxPermSize=33M
-Xmn:205M
转载自:https://www.dutycode.com/jvm_xmx_xmn_xms_shezhi.html