NewGlobalRef слабой ссылки все еще предотвращает сборку мусора - PullRequest
2 голосов
/ 31 мая 2011

Чтобы реализовать функцию обратного вызова из нативного кода в код Java, я должен создать глобальную ссылку, используя NewGloabRef.Из профиля памяти я обнаружил, что после того, как я позвонил env->NewGlobalRef(weak_this), даже если это была слабая ссылка на объект проигрывателя, объект Player будет доступен как корневые объекты, что, я думаю, предотвратит сбор мусора.

Но, насколько я понимаю, слабая ссылка не помешает объекту собрать мусор.

//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 Ответ

1 голос
/ 31 мая 2011

A WeakReference - это объект Java с обычной ссылкой на него. содержит ссылку на другой объект.Это содержащаяся ссылка, которая является «слабой», а не ссылка на саму WeakReference.

Так что, когда вы вызываете env->NewGlobalRef(weak_this) (предполагая, что weak_this является WeakReference), эффект являетсятак же, как присвоение weak_this статическому.Это не приводит к тому, что ссылка на объект , содержащаяся в WeakReference, является полностью достижимой.

Я думаю, что вы, возможно, неправильно истолковываете то, что говорит вам профилировщик памяти.В частности, я ожидаю, что он покажет содержащуюся ссылку WeakReference, которая будет достижимой ... до тех пор, пока GC не решит разорвать связь.Попробуйте поэкспериментировать с WeakReference в обычной переменной static.


ОБНОВЛЕНИЕ

Я начинаю думать, что это нормальное поведение дляJNI NewGlobalRef.Документация JNI (как всегда) очень расплывчата в отношении поведения метода.

Обратите внимание, что существует также метод JNI, называемый NewGlobalWeakRef;см. http://java.sun.com/docs/books/jni/html/refs.html#27531. Если ничего другого, NewGlobalWeakRef предоставляет альтернативный способ делать то, что вы пытаетесь сделать.

...