NewGlobalRef的弱引用仍然可以防止垃圾收集对象 [英] NewGlobalRef of a weak reference still prevent a object from garbage collected
问题描述
为了实现从本地代码到Java代码的回调函数,我必须使用 NewGloabRef
创建一个全局引用。从内存配置文件中,我发现一旦我调用 env-> NewGlobalRef(weak_this)
,即使它是播放器对象的弱引用,Player对象也会可用作根对象,我认为这将防止它被垃圾收集。
但我的理解是,弱引用不会阻止垃圾收集对象。
// java代码
播放器{
$ b $ native_init(新WeakReference(this)),
}
// JNi代码
//监听器
Listener :: Listener(jobject weak_this)
{
//将使用mObject回调
mObject = env-> NewGlobalRef(weak_this);
$ b xxxx_Player_native_init(xxxx。Object weak_this)
{
Listener l = new Listener(weak_this);
$ b编辑:
内存配置文件:
根对象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决定断开链接。在普通静态
变量中尝试使用 WeakReference
进行实验。
更新
我开始认为这是JNI的正常行为 NewGlobalRef
。 JNI文档(一如既往)对方法的行为非常含糊。
请注意,还有一个名为 NewGlobalWeakRef $ c的JNI方法$ C>;请参阅 http://java.sun.com/docs/books/ JNI / HTML / refs.html#27531 。如果没有其他的话, NewGlobalWeakRef
提供了另一种做你正在做的事情的方法。
To implement a callback function from the native code to Java code, I have to create a global reference using NewGloabRef
. From the memory profile , I found that ,once I called env->NewGlobalRef(weak_this)
, even it was a weak reference of the player object, the Player object will be available as Root Objects, which I think will prevent it from being garbage collected.
But my understanding is the weak reference won't prevent the object from garbage collected.
//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);
}
EDIT:
memory profile :
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>
log of JNI
[JNI] NewGlobalRef(0x2C820E10 [com/trident/tv/media/player/JniTPlayer]) : 0x2C820E10
解决方案 A WeakReference
is a Java object with an ordinary reference to it. It contains a reference to another object. It is the contained reference that is "weak", not the reference to the WeakReference
itself.
So when you call env->NewGlobalRef(weak_this)
(assuming weak_this
is a WeakReference
), the effect is the same as assigning weak_this
to a static. It doesn't cause the object reference contained by the WeakReference
to be strongly reachable.
I think you may be misinterpreting what the memory profiler is telling you. In particular, I would expect it to show the contained reference of a WeakReference
to be reachable ... up until the GC decided to break the link. Try an experiment with an WeakReference
in an ordinary static
variable.
UPDATE
I'm starting to think that this is normal behaviour for JNI NewGlobalRef
. The JNI documentation is (as always) very vague about the method's behaviour.
Note that there is also a JNI method called NewGlobalWeakRef
; see http://java.sun.com/docs/books/jni/html/refs.html#27531. If nothing else, NewGlobalWeakRef
provides an alternative way of doing what you are trying to do.
这篇关于NewGlobalRef的弱引用仍然可以防止垃圾收集对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!