我正在使用 jProfiler 来查找 Java swing 应用程序中的内存泄漏。我已经确定了一个不断增长的 JFrame 实例。
此框架打开,然后关闭。
使用 jProfiler 并查看 GC Root 的路径,只有一个参考,“JNI 全局参考”。
这是什么意思?为什么它会挂在框架的每个实例上?
JNI 全局引用是从“本机”代码到由 Java 垃圾收集器管理的 Java 对象的引用。其目的是防止收集仍被本机代码使用但在 Java 代码中似乎没有任何实时引用的对象。
JFrame 是一个java.awt.Window, 并与“本机” Window 对象相关联。当您完全完成一个特定的 JFrame 实例时,您应该调用它的dispose()方法来清理。
我不确定是否有任何本机代码正在创建对 JFrame 的全局引用,但似乎很有可能。如果是这样,这将防止 JFrame 被垃圾收集。如果您正在创建许多 Windows(或子类)并看到它们从未被收集,请确保它们已被处置。
Wikipedia 对Java Native Interface有很好的概述,本质上它允许 Java 和用其他语言编写的本地操作系统库之间的通信。
JNI 全局引用容易发生内存泄漏,因为它们不会自动进行垃圾回收,程序员必须显式释放它们。如果您自己没有编写任何 JNI 代码,那么您使用的库可能存在内存泄漏。
在此处编辑是有关本地与全局引用的更多信息,以及使用全局引用的原因(以及应如何释放它们)
在修复 JavaFX 应用程序中的内存泄漏时,我遇到了这个确切的问题。最后问题是我在调试模式下运行应用程序并且代码中有几个断点。这似乎导致对象成为“JNI 全局引用”并在没有明显原因的情况下保存在内存中。当我关闭调试模式时,一切正常!