原创

OOM 与线程死锁的处理及其工具命令


一、OOM(OutOfMemoryError)问题处理
1. 什么是 OOM?

OOM 表示 Java 程序内存不足,无法继续分配空间,常见异常包括:

java.lang.OutOfMemoryError: Java heap space

java.lang.OutOfMemoryError: Metaspace

java.lang.OutOfMemoryError: GC overhead limit exceeded

java.lang.OutOfMemoryError: Unable to create new native thread

常见原因:

内存泄漏

高并发占满内存

JVM 配置太小

无限创建线程

2. 如何判断是否是 OOM?
2.1 查看日志

搜索关键词:“OutOfMemoryError”。

2.2 查看系统层信息
top -Hp <pid>
ps -ef | grep java
dmesg | grep -i oom

3. OOM 定位方法
3.1 导出 Heap Dump

自动 dump:

-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/opt/dump/


手动 dump:

jmap -dump:live,format=b,file=heap.hprof <pid>

3.2 使用工具分析 dump
工具	用途
MAT	分析内存泄漏、对象占比
VisualVM	查看内存、线程、GC
JProfiler	商业工具,更强大

分析重点:

Leak Suspects

Dominator Tree

Histogram(对象数量)

4. OOM 的解决方式
4.1 调整 JVM 参数
-Xms4g -Xmx4g
-XX:MaxMetaspaceSize=512m

4.2 解决代码问题

常见泄漏点:

静态集合不断增长

未关闭连接(JDBC、Redis)

缓存无过期时间

无限 new 线程

4.3 限流、降级、熔断

适用于流量突增导致的 OOM。

4.4 调整线程池

避免过多线程导致:

java.lang.OutOfMemoryError: unable to create new native thread

二、线程死锁问题处理
1. 什么是线程死锁?

两个或多个线程互相等待对方持有的锁,最终所有线程无法继续执行。

2. 死锁特征

CPU 占用低

程序卡死无响应

jstack 中出现 deadlock

线程状态为 BLOCKED

3. 死锁排查方式
3.1 jstack 排查
jstack <pid> > thread.log


搜索:

deadlock

BLOCKED

waiting to lock

3.2 top 查看线程
top -Hp <pid>


将 tid 转 16 进制:

printf "%x\n" <tid>


然后在 jstack 中查找对应线程。

3.3 可视化工具

VisualVM → Threads 面板查看 BLOCKED 状态

4. 死锁解决方案
4.1 统一加锁顺序

避免:

线程1:A → B  
线程2:B → A


统一改为:

永远先 A,再 B

4.2 使用 tryLock 防止死锁
if (lockA.tryLock(1, TimeUnit.SECONDS)) {
    try {
        if (lockB.tryLock(1, TimeUnit.SECONDS)) {
            // do something
        }
    } finally {
        lockA.unlock();
        lockB.unlock();
    }
}

4.3 减少锁的粒度

缩小 synchronized 范围。

4.4 使用更安全的并发类
传统方式	替代
synchronized List	CopyOnWriteArrayList
HashMap + 锁	ConcurrentHashMap
synchronized	ReentrantLock / StampedLock
三、常用命令总结(收藏)
内存排查
jmap -dump:format=b,file=heap.hprof <pid>
jmap -histo <pid>
jstat -gc <pid> 1000
jps
dmesg | grep -i oom

线程排查
jstack <pid> > thread.log
top -Hp <pid>
ps -mp <pid> -o THREAD,tid,time
printf "%x\n" <tid>

Docker 排查
docker logs <container>
docker stats
docker exec -it <container> bash

四、总结

OOM:通过 Heap Dump 找根因,优化代码 + 调整 JVM。

死锁:通过 jstack 识别锁依赖链,优化加锁顺序或使用 tryLock。

必须结合日志、监控、内存分析、线程分析综合排查
总结
  • 作者:阿杰(联系作者)
  • 发表时间:2025-12-02T07:20:26
  • 版权声明:杰出版
  • 公众号:--无
  • 评论