要实现从 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/