← 中文资源

简体中文版本

Java — OutOfMemoryError: Java heap space

用堆转储、GC 日志和分配分析诊断 Java 堆耗尽,修复泄漏或容量配置,而不是只调大 -Xmx。

阅读英文原文

堆错误是症状

OutOfMemoryError: Java heap space 表示分配失败,而不是堆参数一定设错。存活对象可能泄漏,也可能确实大于配置上限。先从堆转储和 GC 日志入手;猜测 -Xmx 既浪费时间又可能掩盖原因。

java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp -Xmx512m -jar app.jar

泄漏还是容量不足

如果 full GC 反复只能回收很少对象,老年代仍居高不下,说明存活对象在增长。用堆转储找到支配树和引用链。如果存活集稳定且接近上限,可能是堆太小;扩容前先测量 GC 后的存活集。

容器限制

容器中的 JVM 必须考虑堆、metaspace、code cache、线程栈和本地内存。512 MB 容器配 -Xmx512m 没有给其他部分留空间,会被 OOM kill。容器限制应高于 JVM 总占用并留出余量。

验证平台期

运行一次长于原故障窗口的负载测试,同时启用转储和 GC 日志。修复泄漏后曲线会出现平台期;堆太小时会贴近新上限但不会无限攀升。要检查容器内存,而不只是堆。