线上有个小程序,客户反馈的现象是偶发性的卡主没响应,前端失去连接,点其他菜单都没响应。通过查看配置的dump目录有很多的GC日志,以及生成的一个堆内存快照。
JVM的配置参数大概为: -Xms512M -Xmx512M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\dump\ -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:D:\logs\gc-t.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=100 -XX:GCLogFileSize=20M
由于添加了-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\dump\ 所以产生OOM时会自动生成对快照存储方便分析定位问题。
得到了dump文件,使用mat分析:
·查看支配树“Dominator Tree”>>找到最靠前的也就是占用内存最多的前两个。
·进而再继续追踪线程栈,也就是谁在持有它,它从哪里来的。选中然后右键即可。找到Thread Overview and Stacks
·看到具体堆栈信息,类似下面
·然后筛选找到自己业务相关的方法,查看具体的调用路径、实际入参值等信息
·或者在预览界面,直接点击泄露分析,也能一次找到
最终都会到同一个分析页面。
最终发现是有个SQL执行的时候,由于未传入任何条件,导致查询出来的数据很多,之后又去序列化得时候就导致内存溢出了。正确姿势是修改SQL条件,必须至少传入一个有效查询条件,否则不给数据
标签:调用,快照,dump,OOM,偶发,XX,内存,卡顿 From: https://www.cnblogs.com/Nuwa/p/18027331另外如果业务方法是直接调用而非用反射的话,查询定位可能相对更方便。我们这里使用的是反射调用,通过入参去分析具体调用的方法和实际入参值。