Java线上问题排查与调优

  • Post author:
  • Post category:java



一、CPU

首先利用 jps命令找到应用对应的进程id。

top -Hp pid 利用top命令查看该进程ID下的所有线程cpu 占用情况,参数说明:H 打印线程信息,p指定pid,这两个参数的作用是显示进行pid下的所有线程的资源占用情况。

在这里插入图片描述

可以发现占用最高的线程ID是31417。

算出31417对应的16进制为7ab9

jstack -l | grep 0x7ab9查看到该线程的堆栈信息

在这里插入图片描述


二、内存


分析:内存飚高如果是发生在java进程上,一般是因为创建了大量对象所导致,持续飚高说明垃圾回收跟不上对象创建的速度,或者内存泄露导致对象无法回收。

我们会先用free命令先来检查一发内存的各种情况。

在这里插入图片描述


频繁gc


当然我们还是会使用jstack来分析问题,但有时候我们可以先确定下gc是不是太频繁,使用jstat -gc pid 1000命令来对gc分代变化情况进行观察,1000表示采样间隔(ms),S0C/S1C、S0U/S1U、EC/EU、OC/OU、MC/MU分别代表两个Survivor区、Eden区、老年代、元数据区的容量和使用量。YGC/YGT、FGC/FGCT、GCT则代表YoungGc、FullGc的耗时和次数以及总耗时。如果看到gc比较频繁,再针对gc方面做进一步分析。

在这里插入图片描述

定位到了是GC的问题,那么下一步就是找到频繁GC的原因了,所以可以从两方面定位了,可能是哪个地方频繁创建对象,或者就是有内存泄露导致内存回收不掉

导出堆内存文件快照

jmap -dump:live,format=b,file=/home/myheapdump.hprof PID  dump堆内存信息到文件。

使用visualVM对dump文件进行离线分析,找到占用内存高的对象,再找到创建该对象的业务代码位置,从代码和业务场景中定位具体问题。


频繁 Full GC

在使用中发现系统页面打开经常卡顿,通过 jstat 命令发现系统每次 Young GC 后大约有 10% 的存活对象进入老年代。

原来是因为 Survivor 区空间设置过小,每次 Young GC 后存活对象在 Survivor 区域放不下,提前进入老年代。

通过调大 Survivor 区,使得 Survivor 区可以容纳 Young GC 后存活对象,对象在 Survivor 区经历多次 Young GC 达到年龄阈值才进入老年代。

调整之后每次 Young GC 后进入老年代的存活对象稳定运行时仅几百 Kb,Full GC 频率大大降低。



版权声明:本文为qq_20161461原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。