Java调试--实战

CPU占用过高

其他网址

线上服务器CPU占用率高如何排查定位问题?_u011277123的博客-CSDN博客
性能优化之CPU占用率高(一)_一直Tom猫的博客-CSDN博客
线上java程序CPU占用过高问题排查_Vioao's Blog-CSDN博客

什么场景需要排查CPU占用?

  1. 访问接口的响应速度很慢。
  2. 系统崩溃无响应
  3. 压测时要查看CPU、内存、load、rt、qps等指标

排查方法

  1. 找到占CPU最高的进程。
    top命令,记下进程号(PID)。假设最高的是:1893
  2. 通过进程找到对应的线程。
    top -Hp 1893。假设最高的是:4519
    (因为Java是单进程多线程的)
  3. 通过线程定位到代码大概的位置信息。
    printf %x 4519。结果为:11a7
    jstack 1893 | grep  11a7

可能导致CPU使用率飙升的操作

  1. 无限循环的while会导致CPU使用率飙升
  2. 经常使用Young GC会导致CPU占用率飙升
  3. 频繁的GC。
    如果访问量很高,可能会导致频繁的GC甚至Full GC。当调用量很大时,内存分配将如此之快以至于GC线程将连续执行,这将导致CPU飙升。
  4. 序列化和反序列化。稍后将给出一个示例:当程序执行xml解析时,调用量会增加,从而导致CPU变满。
  5. 正则表达式。 我遇到了正则表达式使CPU充满的情况; 原因可能是Java正则表达式使用的引擎实现是NFA自动机,它将在字符匹配期间执行回溯。我写了一篇文章“ 正则表达式中的隐藏陷阱 ”来详细解释原因。
  6. 线程上下文切换。
    有许多已启动的线程,这些线程的状态在Blocked(锁定等待,IO等待等)和Running之间发生变化。当锁争用激烈时,这种情况很容易发生。

内存占用过高

其他网址

Java应用问题定位系列——内存占用过高 - SegmentFault 思否
Java 服务内存占用过高的一次排查过程_谈谈1974-CSDN博客_java服务内存占用过高
java内存占用过高或者cpu占用过高解决_败毒的博客-CSDN博客

简介

定位Java程序内存使用过高或者内存泄漏的问题跟CPU也类似,一般可以分为以下3个步骤:

  1. 定位进程
  2. 定位线程
  3. 定位代码位置

1.定位进程

top

按下M(按内存占用由大到小排序)

// 假设定位到的进程ID为14279。

2.定位线程

top -Hp 14279;

按下M(按内存占用由大到小排序)

top - 18:33:07 up 25 days,  7:48,  1 user,  load average: 0.17, 0.27, 0.23
Threads:  54 total,   1 running,  53 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.5 us,  0.7 sy,  0.0 ni, 98.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  8168236 total,   231696 free,  3660496 used,  4276044 buff/cache
KiB Swap:   969964 total,   969964 free,        0 used.  4197860 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
14293 weiping   20   0 4508772  97036  18112 S  10    12 152:35.42 java
14279 weiping   20   0 4508772  97036  18112 S  5.0  1.2   0:00.00 java
14282 weiping   20   0 4508772  97036  18112 S  0.0  1.2   0:00.37 java

注意观察两点:

  1. 线程的数量
    1. 可以看到,它线程数是54(左上角的Threads项),属于正常。
    2. 若比较大(比如大于1000),要考虑是不是代码有问题:
      1. 是不是代码里手动起了多个线程。比如:使用OkHttpClient时每次都创建了连接池(ConnectionPool);应该是只创建一个连接池的。
      2. 是不是自己创建的线程池最大个数太大了。
  2. 占内存大的线程的PID
    1. 如果线程数量正常,就要dump内存的快照信息来查看。

3.定位代码位置

如果是线上环境,注意dump之前必须先将流量切走,否则大内存dump是直接卡死服务。

dump当前快照:jmap -dump:format=b,file=dump.hprof 14279

查找实例数比较多的业务相关的实例,然后找到相应代码查看。(使用工具查看dump.hprof。比如:MAT,hhat)

死锁

频繁Full GC

猜你喜欢

转载自blog.csdn.net/feiying0canglang/article/details/115105155