NewGlobalRef of a weak reference still prevent a o

2019-07-18 05:07发布

问题:

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

回答1:

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.