CPU飙高、OOM、频繁GC、慢接口 问题排查

103 阅读2分钟

1、CPU飙高:

1、ps -ef | grep 'xxx' 从进程中找到想要排查的进程,例如ps -ef | grep 'java'

返回列表中的pid就是进程id,例如pid = 1

或者使用jps也可以找到进程id

image.png

2、将pid = 1的进程堆栈快照信息dump下来,sudo -uwww jstack -l 1 > stack.log

jstack是java提供的工具

image.png

3、查看进程中cpu过高的线程号:top -p 1 -H

返回中的PID就是线程id

image.png

4、将线程id转化为16进制,因为在堆栈信息中,线程id就是16进制

printf "%x\n" 222

image.png

5、在堆栈信息文件中搜索相关线程id的信息 grep 3bf8d stack.log -A 10

2、OOM

排查思路 与上面大差不差,但是可以将堆快照信息dump下来,借助工具分析对象大小和数量

1、机器摘流

2、jps或者ps -ef | grep '服务名' 获取进程id(pid)

3、sudo -uwww  jmap -dump:format=b,file=xxxx.hprof,将堆快照dump下来

4、云上容器可以直接开http端口下载堆文件:python -m SimpleHTTPServer 1000 (传统机器得用scp、rsync等命令把文件同步到本地)

5、将文件下载到本地 http:// + ip地址 + :1000

6、打开MAT进行堆对象的分析

3、频繁youngGC

JDK默认新生代:老年代 = 1:2,频繁youngGc可能说明新生代内存不够,频繁fullGc可能说明老年代内存不够。

jvm参数 :-XX:NewRatio,默认值是2,表示 老年代(Old Generation)的大小是新生代(Young Generation)大小的 2 倍

默认新生代 eden:suviror1:suviror2 = 8:1:1

jstat -gc ` 观察新生代各个区域(Eden, S0, S1)的大小和已使用量

什么情况下会触发youngGc?

  • eden区空间不足,无法容纳新创建的对象
  • suvivor区空间不足,对象无法从eden晋升到suvivor中,

4、频繁FullGC

FullGC回收的是 整个堆(新生代+老年代)+ 方法区(元空间)

FullGc的触发条件:

  • 老年代空间不足

    • 晋升失败:Young GC后,存活对象需要放入老年代,但老年代剩余空间不足
    • 大对象分配失败:大对象(如长数组)直接进入老年代,但老年代空间不足。
    • 分配担保失败:在Young GC前,若老年代连续可用空间 小于 历次晋升到老年代对象的平均大小,且未开启空间分配担保(-XX:-HandlePromotionFailure),会直接触发FullGC。
  • 方法区/元空间不足:加载的类信息、常量池等占满方法区(或元空间),触发Full GC回收无用类。

  • 显式调用System.gc():建议JVM执行Full GC(实际执行由JVM决定,通常不推荐使用)。

    ref: tech.meituan.com/2017/12/29/…

5、慢接口排查

1、安装arthas
cd /usr/local mkdir arthas cd /arthas curl -O alibaba.github.io/arthas/arth…

2、启动arthas java -jar arthas-boot.jar,然后属于要监听的进程id

image.png

3、trace监听

image.png