使用 JeMalloc 查找 Java 应用程序中的本机内存泄漏



目前我正在尝试解决Java内存问题: 我的 Java 应用程序不断使用越来越多的内存和 最终它被Linux OOM杀手杀死。

可能存在本机内存泄漏,因为经过检查 带有 VisualVM 的 JVM 的元空间和堆看起来都不错。

使用 top 命令我可以看到 JVM 使用的内存 不断增加。

本文中的第一个图形:

示例 #1

与我在自己的应用程序中看到的内容完美匹配。

所以我尝试使用 JeMalloc 来查找泄漏,如各种文章中所述。 在这里我遇到了一个问题:使用 jeprof 命令及更高版本时 Jeprof 本身的 top 命令,它确实显示了使用 内存最多,但这些是十六进制地址,所以我必须 缺少一些符号。但我不知道我需要哪些包裹,这对我来说是未知的。

我已经找到了这个链接: 链接 #1

并安装了这个软件包: debuginfo-install java-1.8.0-openjdk

我尝试先完成简单的步骤:

让 JeMalloc 使用一个简单的应用程序,例如 w。 接下来让它与java版本一起工作。 到目前为止一切顺利,我还可以从JeMalloc获得具有完美概述的PDF。

接下来让它与java -jar simpletest一起工作.jar <<在这里我缺少符号 例如,如果我不在此处关闭GZipInputStream,则不会显示在JeMalloc结果中。

接下来让它与java -jar myapplication一起工作.jar <<在这里我也缺少符号。

所以我的问题基本上是: 我需要什么软件包才能让 JeMalloc 显示所有符号名称来调试应用程序,例如:

public void test1() {
InputStream fileInputStream = null;
GZipInputStream gzipInputStream = null;
try {
fileInputStream = new FileInputStream("test.zip");
gzipInputStream = new GZIPInputStream(fileInputStream);
int data = gzipInputStream.read();
while (data != -1) {
// do something with data
data = gzipInputStream.read();
}
} catch (Exception ex) {
} finally {
// Disabled to see whether JeMalloc can detect the leak
/*try {
if (gzipInputStream != null) {
gzipInputStream.close();
}
if (fileInputStream != null) {
fileInputStream.close();
}
gzipInputStream = null;
fileInputStream = null;
} catch (IOException e) {
e.printStackTrace();
}*/
}
}

使用以下软件:

  • Linux CentOS 7
  • 杰马洛克
  • OpenJDK

找到的文章:

文章 #1

文章 #2

文章 #3

文章 #4

替换分配器(例如使用 jemalloc 或 tcmalloc(来分析内存使用情况可能会提供有关本机内存泄漏源的提示,但它仅限于 JVM 中加载的库中可用的本机代码符号。

要在堆栈跟踪中使用 Java 类/方法,需要生成一个映射文件,将本机代码内存位置与其源相关联。撰写本文时唯一的工具是 https://github.com/jvm-profiling-tools/perf-map-agent

为了在堆栈中获取不仅仅是"解释器"名称,相关代码必须进行 JIT 编译,因此在 JVM 命令行选项上使用-XX:CompileThreshold=1强制执行很有趣(在生产 IMO 中除外(。

在 JVM 中加载代理、生成映射文件和对代码进行 JIT 编译时,perf可用于报告 CPU 分析。内存泄漏调查需要更多的处理。

最好的选择是获取bcc及其memleak工具,如果你的 Linux 内核是 4.9 或更高版本:https://github.com/iovisor/bcc/blob/master/tools/memleak_example.txt

非常感谢布伦丹·格雷格

Debian 系统在一个简单的apt install bcc后就准备好了,但 RedHat 系统需要更多的工作,正如 CentOS 7 在 http://hydandata.org/installing-ebpf-tools-bcc-and-ply-on-centos-7 上记录的那样(在 CentOS 6 上更糟(

作为替代方案,perfonly也可以报告特定探头的泄漏堆栈跟踪。脚本和示例用法可在 https://github.com/dkogan/memory_leak_instrumentation 获得,但必须适应 Java 上下文。

相关内容

  • 没有找到相关文章