弱引用的NewGlobalRef仍然可以防止对象被垃圾收集

时间:2011-05-31 09:18:17

标签: java garbage-collection java-native-interface

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

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

//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

1 个答案:

答案 0 :(得分:1)

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

因此,当您致电env->NewGlobalRef(weak_this)时(假设weak_thisWeakReference),效果与将weak_this分配给静态相同。它不会导致 WeakReference包含的对象引用强烈可达。

我认为你可能会错误地解释内存分析器告诉你的内容。特别是,我希望它能够显示所包含的WeakReference的引用是可以到达的......直到GC决定打破链接。尝试在普通WeakReference变量中使用static进行实验。


<强>更新

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

请注意,还有一个名为NewGlobalWeakRef的JNI方法;见http://java.sun.com/docs/books/jni/html/refs.html#27531。如果不出意外,NewGlobalWeakRef提供了另一种方法来做你想做的事情。