【问题标题】:NewGlobalRef of a weak reference still prevent a object from garbage collected弱引用的 NewGlobalRef 仍然阻止对象被垃圾回收
【发布时间】:2011-05-31 09:18:16
【问题描述】:

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

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

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

【问题讨论】:

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


    【解决方案1】:

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

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

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


    更新

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

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

    【讨论】:

    • Stephen,我在这里添加了内存配置文件和 JNI 日志。一旦我调用NewGlobalRefJniTPlayer 就会出现在根对象部分。而且,我在转储内存配置文件之前强制进行了 GC。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-20
    • 1970-01-01
    相关资源
    最近更新 更多