如何识别JNI全局引用内存泄漏的原因?

时间:2011-06-21 10:32:36

标签: java tomcat memory-leaks garbage-collection java-native-interface

我正在使用Tomcat,在停止我的Web应用程序后,仍然对我的Web应用程序的类加载器实例的引用。 结果是不会释放大量的内存(主要与静态数据相关)。迟早会产生OutOfMemoryError

我拿了一个heap dump,我意识到它由 JNI global reference 保存,阻止类加载器 {{ 3}}

我的应用不使用JNI 。我也没有使用 Apache Tomcat Native Library 。我使用的是Sun / Oracle JDK 我想跟踪这个全球参考的原因/来源。 (我的猜测是JVM内部引用了类加载器 - 但为什么/在哪里?)。

问题:

  • 实现此目的的方法/工具集是什么?

更新

似乎最好的是jssm调试模式引入了JNI全局引用。这帮助了我,但它没有回答这个问题,所以我仍然很想回答可能对将来有用的问题。

4 个答案:

答案 0 :(得分:18)

除了明显的情况:线程,还有一个:

您是否在调试模式下使用应用程序?

除了系统之外,JVM不保留对任何类加载器的引用,但它与您无关。其余的JNI引用是Threads或只是调试持有的对象(前提是你不使用JNI并自己锁定对象)。

JNI引用只是根,编辑你的答案并发布这些引用所持有的对象。

答案 1 :(得分:1)

我要做的第一件事是运行-Xcheck:jni并查看是否有任何问题。我不指望它;听起来JNI并没有发生任何奇怪的事情,只是错误地使用它。但是,确保这一点很好。

如果您使用的是Sun JVM,我认为您可以-XX:TraceJNICalls获取大量JNI呼叫,因为它们会发生。这应该可以让你了解正在进行的调用,并从那里开始研究制作它们的原因,以及为什么会导致问题。

答案 2 :(得分:0)

JRockit任务控制:http://download.oracle.com/docs/cd/E13150_01/jrockit_jvm/jrockit/tools/index.html

一个很好的GUI工具,可以帮助您快速找到它。

答案 3 :(得分:0)

您可以尝试jstack

可能列出的堆栈跟踪之一会显示全局引用的来源。