cpu过高、项目运行慢:
进入Linux重端命令行 top 命令:找到java 进程号 7498
2.执行 top -p 7498 单独监控该进程,页面:
3、在第 2 步的监控界面输入 H,获取当前进程下的所有线程信息:发现7501、7500两个线程占用内存最大。
4、执行
jstack 7498
对当前的进程做
dump
,输出所有的线程信息,随机截图:
5、里面的线程id 是16进制,随机找到一个截图:
6
将第 3
步得到的线程编号 7500
通过计算器
转成
16
进制是 1D4C、1D4D
或者 printf "%x\n" 7500 生成1D4D 然后 : jstack 7498|grep 1D4D -C 10
7、
根据第
6
步得到的 1D4D
在第
5
步的线程信息里面去找对应线程内容:
8
解读线程信息,定位具体代码位置,发现是两个垃圾回收的线程占用过多的线程资源,疯狂的垃圾回收导致系统变慢;看看日志(加上打印垃圾回收的日志)还有OOM异常;
发现新生代不进行垃圾回收,一直进行FGC垃圾回收,5秒钟进行10次,全部时间用来FGC。WAY!!!,找原因!!!!
9、jmap -heap 7498
发现老年代已经塞满。
10、查一下这个进程的占据内存的前20名的对象,找到代码中相应的类,命令: jmap -histo 7498 | head -20
业务代码类找到了,就去项目中看看,这时所有问题都迎刃而解了!!!
今天实战线上排查到此结束!
注意!!!
原因:
业务场景1,此线程有非常多或非常大的对象存在,并且处理这些对象的过程很慢、很耗时,即此线程不结束,对象引用一直存在,不会变成垃圾,因此,GC频繁进行,内存也不会有变化。
业务场景2:内存泄漏引起OOM异常,该回收的垃圾,回收不了,造成系统变慢。如:map中 对象作为key 而没有重写 hashcode 和equal 方法。
业务场景3:慢sql查询大的数据量,导致数据库连接数紧张。