什么是“JNI全局引用”?

34
我正在使用 jProfiler 来查找 Java Swing 应用程序中的内存泄漏。我已经确定了一个 JFrame 实例的数量不断增加。
这个窗口被打开,然后关闭。
使用 jProfiler 并查看到 GC 根路径时,只有一个引用:'JNI 全局引用'。
这是什么意思?为什么它会保留每个框架实例?
3个回答

24

JNI全局引用是指从“本地”代码到由Java垃圾回收器管理的Java对象的引用。其目的是防止在Java代码中没有活动引用的情况下仍被本地代码使用的对象被回收。

JFrame是一个java.awt.Window,与一个“本地”窗口对象相关联。当您完全完成特定的JFrame实例时,应调用其dispose()方法进行清理。

我不确定是否有任何本地代码创建了对JFrame的全局引用,但这似乎很可能。如果有,这将阻止JFrame被垃圾回收。如果您正在创建许多窗口(或子类)并发现它们永远不会被回收,请确保它们已被处理。


如果代码只有Java,这很可能是最合理的解释。我曾经在使用JNI时遇到过全局指针的问题。 - Mario Ortegón

19

维基百科对Java Native Interface有一个很好的概述,它实质上允许Java与使用其他语言编写的本地操作系统库进行通信。

JNI全局引用容易出现内存泄漏问题,因为它们不会自动进行垃圾回收,程序员必须显式释放它们。如果您自己没有编写任何JNI代码,则您使用的库可能存在内存泄漏问题。

编辑这里有关于本地引用和全局引用的更多信息,以及为什么使用全局引用(以及如何释放它们)。


3
维基百科是一种次级来源。主要来源和官方文件是 JNI 规范 - user207421

15

在修复JavaFX应用程序中的内存泄漏问题时,我也遇到了这个确切的问题。最终问题是由于我在代码中运行调试模式并设置了几个断点。这似乎导致对象成为“JNI全局引用”,并且在没有明显原因的情况下保留在内存中。当我关闭调试模式时,一切都正常工作!


2
糟糕,这正是刚刚发生在我身上的事情! - Hakanai
1
这里还有一个.. 哈哈 - Bruno Medeiros

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接