线上问题排查方案总结

cpu飙高排查

CPU 飙高的几种常见场景:

  • 死循环
  • 垃圾回收频繁触发
  • 锁竞争(死锁)
  • 高频率 I/O 操作
  • 大规模的对象序列化/反序列化
  • 高并发请求下线程池耗尽
  • JVM 参数不合理
  • 内存泄漏导致的 Full GC 频繁触发

1. 确认 CPU 占用高的进程

确认问题进程:使用 top 或 htop 命令来查看哪个进程占用了较高的 CPU,找到占用CPU最高的Java进程。

2. 查看进程的线程情况

确认哪个线程占用了高 CPU,可以使用 top -H 来查看单个线程的 CPU 使用情况:

top -Hp <PID>

这里,<PID> 是在第 1 步中找到的 Java 进程 ID。找到占用 CPU 高的线程,并记录下其线程 ID (TID)。注意,TID 是十进制表示的。

3. 将线程 ID 转换为十六进制

Java 堆栈通常使用十六进制来表示线程 ID。需要将高 CPU 占用的线程 ID 转换为十六进制:

printf "%x\n" <TID>

例如,假设线程 ID 是 12345,则运行:

printf "%x\n" 12345

输出的结果是十六进制的线程 ID,比如 3039

4. 生成 Java 线程 dump

使用 jstack 命令生成 Java 进程的线程 dump。

jstack <PID> > jstack_output.txt

其中 <PID> 是第 1 步中找到的 Java 进程 ID。这个命令会生成当前 Java 进程的所有线程的堆栈信息,并将输出保存到 jstack_output.txt 文件中。

5. 分析线程 dump

打开生成的 jstack_output.txt,搜索第 3 步中得到的十六进制线程 ID (0x3039)。找到对应的线程堆栈信息。

堆栈信息中会显示该线程正在执行的 Java 方法,可以根据这些信息分析是什么代码逻辑导致了 CPU 占用过高。

总结

  1. 确认问题进程:使用 tophtop 找到 CPU 占用高的 Java 进程。
  2. 查看线程情况:使用 top -Hp <PID> 查看该进程的各个线程 CPU 占用情况,记录高 CPU 占用线程的 TID。
  3. 转换线程 ID:将 TID 转换为十六进制,使用 printf "%x\n" <TID>
  4. 生成线程 dump:使用 jstack <PID> 生成线程堆栈,保存至文件。
  5. 分析堆栈信息:在 dump 文件中搜索十六进制 TID,分析该线程的执行方法,排查高 CPU 的原因。

内存溢出(OutOfMemoryError)

OutOfMemoryError(简称OOM)是Java虚拟机(JVM)在无法分配足够内存时抛出的错误。当JVM中的内存耗尽,无法为新对象或数组分配空间时,就会抛出这个错误。


一、OOM的常见类型
OutOfMemoryError 有多种类型,排查时需要通过日志或异常信息确定具体的内存溢出原因。常见类型包括:

  • Java Heap Space:Java 堆内存不足,无法分配对象。
  • Metaspace/PermGen Space:类的元数据空间不足(JDK 8 之后为 Metaspace,之前为 PermGen)。
  • GC Overhead Limit Exceeded:垃圾回收频率过高,JVM 花费太多时间进行垃圾回收,且回收效果不佳。
  • Direct Buffer Memory:直接内存不足。
  • Unable to Create New Native Thread:系统线程资源耗尽,无法创建新的线程。

二、OOM的常见原因
内存泄漏

  • 对象不再使用但仍被引用,导致GC无法回收
  • 常见于静态集合、缓存、监听器等场景

堆大小设置不合理

  • -Xmx设置过小,无法满足应用需求
  • 未根据应用实际情况调整JVM参数

大对象/大数组

  • 一次性加载大量数据到内存
  • 处理大文件时未使用流式处理

高并发场景

  • 大量请求同时处理,创建过多对象
  • 线程池设置不合理,创建过多线程

三、JVM OOM 排查手段
首先查看日志,java.lang.OutOfMemoryError 日志包含具体的 OOM 类型。


1、使用 jstat 查看 GC 情况
jstat -gc 命令,你可以快速获取 JVM 的垃圾回收统计信息

场景:
场景1:内存泄漏诊断:OU持续增长,即使Full GC后也不下降 → 可能存在内存泄漏
场景2:新生代配置不合理:YGC非常频繁(每秒多次)且每次回收量少 → 考虑增大新生代
场景3:系统停顿问题:FGCT突然增大 → 检查是否有大对象直接进入老年代

在这里插入图片描述


2、jmap:生成堆转储文件

当应用遇到 OutOfMemoryError 时,生成堆内存 Dump 文件是排查内存泄漏或异常内存使用的第一步。生成堆内存 Dump 后,可以使用内存分析工具对 dump 文件进行深入分析。(用 jvisualvm 等工具)

方式1:手动生成 Dump:如果应用还在运行中但内存使用异常高,可以通过以下命令手动生成 dump 文件:

jmap -dump:format=b,file=heapdump.hprof <PID>

方式2: 在 JVM 启动参数中添加如下配置:
bash -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<路径>
这样,当发生 OutOfMemoryError 时,JVM 会自动生成堆内存 dump 文件,保存所有对象的当前状态。(有时候内存溢出后程序直接中断,所以需要通过 vm 参数的方式获取 Dump 文件)

3、VisualVM,JConsole等工具

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值