JVM线上初次实战问题排查和解决
原因:公司项目多次oom内存泄漏导致了客户的极大不满,最后这一个任务交给了我一小白,压力大,但是经过实战分析发现这也是一次经验,所以来分享。
内存溢出说复杂很复杂 说不复杂 搞懂jvm原理其实很简单 ,几乎都是百度解决 自己jvm原理不是很懂,所以请教了y一些群里大佬的帮助。
记录一下我解决过程
1.工具
工具的使用能大幅度提升解决OnOutOfMemoryError问题
工具有: 监控堆和cpu 工具( jvisualvm) 和分析dump 工具(mat)
对于我来说这二个工具必不可少。
具体怎么用百度就行
2.命令
命令也是最必要的 监控内存 cpu 命令
jump top jstat 等
这些命令可以查看内存垃圾回收次数以及很有效的监控内存和cpu的变化
具体百度就行
3.如何解决
经过上面的监控 和压测,一般压力测试要考虑到:
业务峰值来算这些的,核心接口每秒多少请求,每次请求多少个对象,
对象多大,每秒使用多少内存 计算eden区多少时间占满,
发生一次young gc 多少对象存活,多少对象进入老年代,老年代增长速率
经过这些 可以根据服务器的内存大小限制内存和堆内存
项目出的问题是因为由于full gc 越多,说明老年代经常放不下 young gc
过来的存活对象, 老年代的gc 触发(stw) 如果老年代清理之后 还是放不下,
就产生了oom了 (借由大佬的原话)
以及自己排查出了服务器调用的缓存过大导致了oom。
解决方式采用的cms回收器(百度查看一下该回收器原理即可)模版
根据服务器限制内存
Xms4096M 初始堆大小
-Xmx4096M 堆最大值
-Xmn3072M 堆年轻代大小
-Xss1M 设置线程栈大小
-XX:MetaspaceSize=256M metaspace的大小
-XX:MaxMetaspaceSize=256M metaspace的最大大小
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFaction=92 CMS垃圾收集器,当老年代达到92%时,触发CMS垃圾回收
-XX:+UseCMSCompactAtFullCollection 打开对老年代的压缩,可能会影响性能,但可以消除堆碎片
-XX:CMSFullGCsBeforeCompaction=0 每次CMS GC后对堆空间进行压缩、整理
-XX:+CMSParallelInitiaMarkEnabled 初始标记并行执行
-XX:+CMSScavengeBeforeRemark 在Full GC之前触发一次Young GC
-XX:+DisableExplicitGC 禁止使用System.gc
-XX:+PringGCDetails 开启GC日志
-Xloggc:oomgc.log 日志文件输出路径
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/user/local/vump/oom
上面是参数解决 刚刚说到缓存太多可以采用LRU策略来清理缓存(百度查看一下)
目前我用的这二种 在测试中发现oom时间减少了很多很多 后期继续优化
在此说到代码优可以mat工具和打印出的服务器日志去查看
自己项目中一些垃圾代码和频繁new 进行代码优化
以上则是我第一次的调优实战 希望能帮助大家,jvm总的来说还是要搞懂原理这样解决起来就很简单了。