【发布时间】:2015-11-23 03:43:56
【问题描述】:
问题
我们正试图找出 Web 应用程序中出现大内存泄漏的罪魁祸首。我们在查找内存泄漏方面的经验非常有限,但我们发现了如何使用jmap 进行 Java 堆转储并在 Eclipse MAT 中对其进行分析。
但是,我们的应用程序使用 56/60GB 内存,堆转储的大小只有 16GB,在 Eclipse MAT 中甚至更小。
上下文
我们的服务器在 Ubuntu 14.04 上为我们的 java 应用程序使用 Wildfly 8.2.0,其进程使用了 95% 的可用内存。进行转储时,我们的缓冲区/缓存使用空间为 56GB。
我们使用以下命令创建转储:sudo -u {application user} jmap -dump:file=/mnt/heapdump/dump_prd.bin {pid}
堆转储文件大小为 16.4GB,在使用 Eclipse MAT 分析时,它显示大约有 1GB 活动对象和约 14.8GB 无法访问/浅堆。
编辑:以下是有关我们看到的问题的更多信息。我们监控我们的内存使用情况,我们看到它不断增长,直到剩下大约 300mb 的可用内存。然后它会停留在该内存量附近,直到进程崩溃,不幸的是应用程序日志中没有错误。
这使我们假设这是一个严重的 OOM 错误,因为这只发生在内存接近耗尽时。我们为我们的 JVM 使用设置 -Xms25000m -Xmx40000m。
问题
基本上,我们想知道为什么我们的大部分内存没有在此转储中捕获。顶级保留大小类看起来不太可疑,所以我们想知道是否有一些与堆转储相关的东西我们做错了什么。
【问题讨论】:
-
您如何测量应用程序的内存使用情况?仅仅因为Java进程使用
X的内存量,并不意味着Java堆是X。 -
好的,我们正在使用linux命令
free -h来查看我们的内存使用情况。 -
"直到进程崩溃,不幸的是应用程序日志中没有错误" - 检查包含服务器可执行文件的目录;这通常是调用“java”命令的目录,也是 JVM 将创建崩溃报告文件的目录。看看是否存在这样的文件,它可能会提供线索。您所描述的听起来像是虚拟机硬崩溃,而不是普通的 Java 应用程序异常。
-
您是否正在从 JVM 捕获标准输出和标准错误?如果没有,请尝试将它们重定向到文件,您可能会在那里看到异常。
-
感谢 Gimby 和 schtever 的建议,非常感谢!
标签: java memory-leaks heap-memory heap-dump jmap