java jvm内存溢出实例重启排查生产实战(使用VisualVM)
背景
项目组线上生产环境不定期的发生内存爆满然后实例重启,实例发布上线后实例内存不断增长最后维持在百分之九十多,十分危险。因此我参与到了排查中,本篇博客将记录排查过程和思路。
第一步:看报错
在日志中搜索error exception timeout等关键词来定位收集错误日志,并优先将报错的bug解决。
既然有内存溢出,少不了你能看到OutOfMemoryError这个报错,意思就是内存溢出错误。
第二步:看链路跟踪、机器指标监控等监控平台
云厂商比如腾讯云阿里云华为云都会有链路跟踪产品,或者是常见的pinpoint 、skywalking等
监控这边云平台也有,还有普鲁米修斯Prometheus之类的平台,随便百度都能搜到,记住选的时候要考虑主流的,生态完善的,社区活跃的,适合国内的,适合项目的和现有硬件配套的适合自己用的。
在问题排查过程中,有效的监控工具会让你更快更方便的掌握系统现状信息,更快的发现问题位置。
在链路跟踪中,你可以查看接口调用量、接口调用链路、接口每步耗时、慢接口、慢SQL、慢调用、异常信息、jvm信息、GC信息等
-
找慢接口
慢接口的业务代码里可能会有不恰当的低性能实现方案,例如全表扫描、大量数据加载、模糊匹配、大量遍历、new大量对象、死锁等操作,若发现应予以优化解决。 -
看接口调用量
看下接口调用量的变化,是否有异常流量突增导致系统无法处理大量请求,检查接口的请求量是否符合业务平时的正常数值,若有异常流量核实流量来源,成因,并及时做出应对措施。 -
慢SQL
用explain查看执行计划,找到开发者了解这个SQL的业务需求,并对SQL进行优化,例如使用恰当的索引、做时间范围限制、避免在查询条件中使用函数导致索引失效等 -
慢调用
有可能当前业务代码并不慢,而是下游服务或者第三方服务慢,则考虑优化下游服务或者将第三方调用改为异步实现,或考虑使用缓存等措施来提高性能。 -
new大量对象
在new对象、读取数据库数据的时候要考虑尽量使用更少的内存,更多的复用,更少的读取关键数据来实现原本的业务逻辑,错误的方式比如只需要某个表的所有ID字段,在查询时将所有字段的数据查询出来了。只需要指定某个表有多少条数据,却将表所有数据查出来然后获取集合大小。
在代码逻辑中你仍然可以优化,例如创建集合时提前预估容量并指定容量new集合,避免集合做多次扩容操作浪费资源损耗性能。插入大量数据时一条条插入,可以优化为每1000条为一批生成SQL来批量插入等,性能优化的这些技巧需要不断学习和实践,看优秀的源码也可以学习到很多优秀的写法。 -
异常信息
也就是看报错信息,找到报错代码行,解决bug。或者是jvm级别的报错则分析报错原因,引发报错的业务代码位置,进行优化、bug解决。 -
看jvm信息
你可以看jvm线程数是否有突增、堆内存是否有突增、年轻代老年代内存使用情况,是否内存不够,直接内存是否一直增长,类加载个数、元空间内存是否持续增长(有些框架或者代码会去不断生成新的代理类~),线程状态是否有阻塞的线程 -
看GC信息
通过查看jvm的内存回收GC记录也能够得到一些信息,例如在某些时候GC频繁,证明内存频繁不足,若是年轻代的minor GC频繁证明创建对象操作比较多,新生代内存需要不断的回收才能满足频繁创建对象的需要,而FullGC(也就是MajorGC)触发的时候,证明你的老年代内存也不足了,那么你要考虑是否有大量强链接对象占据了老年代内存,你可以指定jvm参数,在jvm内存溢出的时候导出堆内存,然后使用VisualVM这样的工具来分析堆文件(.dump/.hrof)。
第三步:导出堆文件使用VisualVM分析
MAT之类的工具也可以,自行选择。
java jvm堆内存分析工具MAT(导出运行中jvm堆内存、加载导出文件分析)
加载堆文件
第一眼看一下概要信息
来分析对象
点开char[]会发现大量的char[]数组,这个你肯定和熟悉,String里就是char[]
然后你可以随机抽查一些字符串里的内容看看,点左边的+号,展开看内容或者引用链路,可以看到这个字符串是什么对象里引用的,有助于分析。这次问题排查的时候从这边抽查发现了大量的某个类的实例,里面存了大量字符串。于是通过这个类最后定位到了一个调度,有人写了查询二十多万条数据出来直接装List里,真是绝了。浪费多少内存。
额外你可以用包聚合的方式来从查看对象,发现某个包下的某个vo对象居然有11万个,这也是占用了大量内存,需要优化的地方。
还可以以实例维度来排序
这个最大的对象里有24万个item,你就说恐怖不恐怖,一看是数据库查询了这么多数据,人才
第四步:考虑jvm参数优化、arthas进入jvm分析等操作
根据项目业务,分配合理的内存,根据机器配置之类的去合理选择垃圾回收器等,这些暂时先不写了~ 找相关资料、博客看呗