传统项目和互联网项目常见jvm问题
-
传统项目与互联网项目的区别
-
传统项目所遇到的jvm问题
# 当单个接口响应特别慢时
先考虑是否有sql慢查询,定位慢查询的⽅法⼀般是⽤explain查看sql的执⾏计划
- FullGC与MinorGC的区别
Minor GC触发条件:当Eden区满时,触发Minor GC
FullGC触发条件
1、调⽤ System.gc() 此⽅法的调⽤是建议 JVM 进⾏ Full GC,虽然只是建议⽽⾮⼀定,但很多情况下它会触发 Full GC。
因此强烈建议能不使⽤此⽅法就不要使⽤,让虚拟机⾃⼰去管理它的内存。可通过 -XX:+ DisableExplicitGC 来禁⽌ RMI 调⽤ System.gc()
2、⽼年代空间不⾜ ⽼年代空间不⾜的常⻅场景为前⽂所讲的⼤对象直接进⼊⽼年代、⻓期存活的对象进⼊⽼年代等,当执⾏ Full GC 后空间仍然不⾜,
则抛出Java.lang.OutOfMemoryError。为避免以上原因引起的 Full GC,调优时应尽量做到让对象在 Minor GC 阶段被回收、让对象在新⽣代多存活
⼀段时间以及不要创建过⼤的对象及数组
3、空间分配担保失败 使⽤复制算法的 Minor GC 需要⽼年代的内存空间作担保,如果出现了HandlePromotionFailure 担保失败,则会触发 Full GC
此项⽬中出现频繁FullGC,也就是系统空间分配不⾜导致的系统堆内存强制回收
问题解决⽅法分析
由于本机单服务内存过⼤导致,此场景下Full GC,⽽且需要回收的内存很⼤,持续时间过⻓
解决停顿时间过⻓问题,缩短GC时间
- 下载导致的频繁FullGC问题
# 原因:⽤户线程访问所导致的⼤对象问题
# 模拟该问题
-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
- 解决方案
32G内存-xmx30G,系统每次进⾏FullGC时⻓太⻓
可以减少-xmx⼤⼩成4G,从⽽缩短Full GC
最终解决⽅案:集群部署,第⼀个节点4G 第⼆个节点4G 第三个节点4G ⽤nginx配置转发upstream
- 互联网项目jvm问题
访问量⼤就越容易出问题
判断⼀个⽤户是否在⽩名单,使用list集合来做,List.contain(⽤户)返回true则表示存在,当访问量增大时使用set集合来做,Set.contain(⽤户),通过hash⽐较,当访问量再次增大时,使用布隆过滤器
案例1,关于死锁问题
解决⽅案:jstack -m命令查看帮我们检测是否有死锁,或者jconsole、jvisualVM也能检查
new Thread的时候最好带上名称
案例2,堆内存泄漏问题
现象:出现OOM或者Full GC,heap使⽤率明显上升,经常达到Xmx
Full GC出现的正常频率是⼤概⼀天⼀到两次
解决⽅案:jmap dump下内存/heap dump on OOM/heap dump on FullGC+jhat本地分析,或者jconsole、jvisualVM也能检查
案例3,堆外内存泄漏
现象:heap使⽤率很低,但是出现了OOM或者Full GC
解决⽅案:可以⽤btrace跟踪DirectByteBuffer的构造函数来定位