记录一次JVM调优实战
一、问题分析思路
1.考虑一个问题现象,系统刚启动在访问量比较小的时候运行流畅,随着访问量提高,开始卡顿;
2.可以先排查数据库问题,例如Oracle可以检查临时表空间,慢sql统计,索引等等因素,如果依然无法解决;
3.最终再考虑JVM调优,正常情况下是不需要JVM调优的,个人以为,JVM调优更多是针对比较极端的情景的。
4.为什么会系统卡顿? 结合个人见过的问题,一般都是堆上发生的GC,导致系统停顿时间过长,或者过于频繁进行GC,它们都会造成性能损耗,不用猜,此时一般都是在OOM问题的边缘来回试探了。
5.OOM问题表现:
内存泄露
比如出现异常或者代码bug,某些对象产生后就不能被回收。已知:一般情况下,对象在新生代上分配,如果多次收集后依然存活则进入老年代(大对象会直接进入老年代)。不能被回收的对象,会不断占用老年代空间 最终,老年代内存空间占满,新生代对象需要晋升时无法请求到足够内存空间,进入Full GC环节。
性能较差代码导致大量对象无法被快速回收
该问题表现为,在堆内存空间还有剩余时,假设堆上限8G,只要还剩余一定空间时,例如:几百M、或者1G,手动触发Full GC,老年代就会被回收掉,但是放任不管,最终肯定会因为对象分配速度过快导致堆内存占满。
PS *
- Full GC (STW操作,所有用户线程停顿)
- Minor GC/Young GC–目标是新生代的垃圾收集,新生代空间不足时触发,新生代中对象根据存活次数判定是否晋升
- Major GC/Old GC–目标是老年代的垃圾收集
- Mixed GC --目标是整个新生代和部分老年代的垃圾收集(只有G1垃圾收集器存在该行为)。
其实很好理解:Full GC是较难触发的(可以自行了解Full GC触发条件),一般都是较为极端的情况才会触发Full GC;
区别是:
- full gc频率极低,且full gc 能回收掉大量资源,那么你是个好人,你可以走了;
- full gc频率高,并且不能有效回收内存空间,那么可以证明你不对劲,要把你抓起来。一般会指向OOM问题
理解为:我大意了,我没有闪,直到最后知道Full GC到来的我眼泪掉下来。。。。。
PS* 此时或许确实有许多对象可以被回收,但是了解回收算法的人都应该需要知道:
- G1的标记整理算法,需要额外有剩余空间才能进行对象的整理,如果堆空间占满了,那么能整理到哪里去呢?此时Fu

本文通过实战案例,分析了系统卡顿及内存溢出的原因,介绍了如何使用JVisualVM和JProfile等工具进行JVM调优,包括识别性能瓶颈、解决内存泄漏等问题。
153

被折叠的 条评论
为什么被折叠?



