java - 弱引用的 NewGlobalRef 仍然阻止对象被垃圾收集

标签 java garbage-collection java-native-interface

要实现从 native 代码到 Java 代码的回调函数,我必须使用 NewGloabRef 创建一个全局引用。从内存配置文件中,我发现,一旦我调用 env->NewGlobalRef(weak_this),即使它是播放器对象的弱引用,播放器对象也将作为根对象可用,我think 会阻止它被垃圾收集。

但我的理解是弱引用不会阻止对象被垃圾回收。

//java code

Player{

native_init(new WeakReference(this)),

}

//JNi code

//listener 
Listener::Listener(jobject weak_this)
{

//will use mObject for callback 
mObject = env->NewGlobalRef(weak_this);

}


xxxx_Player_native_init(xxxx. Object weak_this)
{

Listener l = new Listener(weak_this);

}

编辑:

内存配置文件:

 Root Object 0x2C820E10 <com/trident/tv/media/player/JniTPlayer>
  com/trident/tv/media/player/JniTPlayer.trace : 0x2C83CC54 <java/lang/String>
  com/trident/tv/media/player/JniTPlayer.listenerList : 0x2C820E64 <java/util/Vector>

JNI的日志

[JNI] NewGlobalRef(0x2C820E10 [com/trident/tv/media/player/JniTPlayer]) : 0x2C820E10

最佳答案

WeakReference 是一个带有普通引用的 Java 对象。它包含对另一个对象的引用。包含的引用是“弱”的,而不是对 WeakReference 本身的引用。

所以当你调用env->NewGlobalRef(weak_this)时(假设weak_this是一个WeakReference),效果和赋值是一样的weak_this 为静态。它不会导致包含 WeakReference 的对象引用是强可达的。

我认为您可能误解了内存分析器告诉您的内容。特别是,我希望它显示包含的 WeakReference 引用是可访问的……直到 GC 决定断开链接。尝试在普通 static 变量中使用 WeakReference 进行实验。


更新

我开始认为这是 JNI NewGlobalRef 的正常行为。 JNI 文档(一如既往)对方法的行为非常模糊。

请注意,还有一个名为 NewGlobalWeakRef 的 JNI 方法;见http://java.sun.com/docs/books/jni/html/refs.html#27531 .如果不出意外,NewGlobalWeakRef 提供了一种替代方法来完成您正在尝试做的事情。

关于java - 弱引用的 NewGlobalRef 仍然阻止对象被垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6185431/

相关文章:

java - 如何在 DllMain 调用中维护 JVM 指针并防止调用 JNI_CreateJavaVM 两次

java - 如何让 JavaCritical 真正在 JNI 上工作

java - 类型的通用方法

android - dalvik的垃圾收集工具

android - Android-JNI 检测到应用程序错误中 AndEngine GLES2 的 Proguard 问题

java - 保留对对象的引用以供将来的方法调用或每次在长方法中获取对象

garbage-collection - 没有用于低级编程的垃圾收集器的 Lisp

java - 如何在用户浏览器中更改 url 而无需在 servlet 中进行客户端重定向

java - Facebook 应用程序的测试帐户(例如 JUnit 测试手册)

java - 最近更新了R/RStudio,rJava无法加载。