java - 分析/追踪 JVM 中潜在的 native 内存泄漏

标签 java linux memory memory-leaks

我们正在使用 Java 1.6(OpenJDK 和 Oracle JDK)在 Linux 上运行一个应用程序。 JVM 本身有最大 3.5 GB 堆和 512 MB permgen 空间。然而,运行一段时间后,top 报告该进程正在使用大约 8 GB 的虚拟内存,而 smem -s swap p 报告大约有 3.5 GB 被交换。

在一台服务器上运行数千个图像文件的更大导入后,几乎没有交换空间,并且由于操作系统未能为这些应用程序分配内存,对 native 应用程序的调用(在我们的例子中是 Im4java 调用 Image Magick)失败.

在另一种情况下,交换空间在数周内填满,导致操作系统因交换空间不足而杀死 JVM。

我知道 JVM 需要超过 4 GB 的内存用于堆(最大 3.5 GB)、permgen(最大 512 MB)、代码缓存、加载的库、JNI 框架等。

我遇到的问题是如何找出实际使用了多少内存。如果 JVM 堆内存不足,我会得到一个可以分析的转储,但在我们的例子中,操作系统内存被耗尽,因此 JVM 不会生成转储。

我知道 JRockit 有 jrcmd,但不幸的是我们不能只切换 JVM。
似乎还有一些库可以跟踪 native 内存使用情况,但其中大多数库似乎需要重新编译 native 代码 - 除了 Im4java(AFAIK 只运行 native 进程,我们不使用 DLL/SO-此处集成)和 JVM,据我们所知,不涉及其他 native 代码。

除此之外,我们不能使用可能对性能或稳定性产生巨大影响的库/工具来长期(数周)跟踪生产系统上的内存使用情况。

所以问题是:

我们如何获得有关 JVM 实际需要所有内存的信息,最好是一些详细信息?

最佳答案

在 JVM 中替换内存分配器(jemalloc 或 tcmalloc)时,您可能会发现对“zlib/gzip”(自 Java 7 起的 pdf 处理或 http 编码)、“java2d”或“jai”的引用。

但要真正诊断 native 内存泄漏,需要 JIT 代码符号映射和 Linux 最近的分析工具:perfperf-map-agentbcc.

详见相关回答https://stackoverflow.com/a/52767721/737790

非常感谢Brendan Gregg

关于java - 分析/追踪 JVM 中潜在的 native 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26343377/

相关文章:

java - 从 DOM 对象创建的 ArrayList 中删除属性,也会将它们从原始文档中删除。我究竟做错了什么

node.js - 如何更改 npm install 的 shell

c++ - 无法访问存储在多维 vector 中的对象 (C++)

java - EJB客户端如何定位没有url的EJB服务器?

java - Eclipse 在将 GaussianBlur 与 OpenCV for Android 一起使用时出错

java - 连接到 .NET REST 端点的 Android 中的对等错误间歇性连接重置

linux - 新起搏器中的 crm_mon 命令不能像旧行为一样工作

c - 队列 Linux 无法写入

c - C中结构成员(指针与数组)的内存分配之间的差异

java - 如果 Java 应用程序出现内存泄漏,JVM 最终会耗尽内存并标记,对吗?