温馨提示×

ubuntu java内存溢出咋办

小樊
37
2026-09-16 07:54:53
栏目: 编程语言

在 Ubuntu 上遇到 Java 内存溢出(OutOfMemoryError),一般按下面思路处理和排查。


一、先确认是哪种内存溢出

Java 常见 OOM 类型:

  1. Java heap space(堆内存不足)
  2. Metaspace / PermGen(类元数据区不足)
  3. Unable to create new native thread(线程数过多)
  4. GC overhead limit exceeded(GC 频繁但回收少)
  5. Direct buffer memory(NIO 直接内存)

看错误日志里具体是哪一句。


二、临时解决办法(先让服务跑起来)

1. 增大 JVM 内存(最常见)

编辑启动脚本或 systemd 配置:

java -Xms512m -Xmx2048m -jar app.jar

Ubuntu 上如果是 systemd 服务:

sudo systemctl edit your-app.service

添加:

[Service]
Environment="JAVA_OPTS=-Xms512m -Xmx2048m"

然后:

sudo systemctl daemon-reload
sudo systemctl restart your-app

2. 元空间不足(Metaspace)

-XX:MetaspaceSize=128m
-XX:MaxMetaspaceSize=512m

3. 线程数过多

  • 减少线程池大小
  • 检查 ulimit -u
ulimit -a

三、排查根本原因(重点)

1. 开启 Heap Dump(非常关键)

-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/var/log/app/heapdump.hprof

OOM 后分析:

  • MAT(Eclipse Memory Analyzer)
  • jhat
jhat heapdump.hprof

2. 实时监控内存

jstat -gcutil <pid> 1000

查看:

  • EU / OU( Eden / Old 使用率)
  • FGC(Full GC 次数)

3. 查看进程内存占用

top -p <pid>
ps -eo pid,comm,rss,vsz

4. 常见导致 OOM 的原因

  • 集合类(List / Map)无限增长
  • 缓存未设上限
  • 大文件一次性读入内存
  • 内存泄漏(对象无法回收)
  • 线程池配置错误

四、Ubuntu 系统层面检查

1. 系统内存是否真的不足

free -h

2. swap 是否开启

swapon --show

3. OOM Killer 是否杀进程

dmesg | grep -i "killed process"

五、推荐标准 JVM 参数模板

JAVA_OPTS="-Xms1g -Xmx2g \
-XX:MetaspaceSize=128m \
-XX:MaxMetaspaceSize=512m \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/var/log/app/oom.hprof \
-XX:+PrintGCDetails \
-Xloggc:/var/log/app/gc.log"

如果你愿意,可以把:

  • 完整报错信息
  • Java 版本
  • 服务类型(Spring / Tomcat / 自写程序)

发出来,我可以帮你精准定位原因。

0 踩