2011-05-31 82 views
2

要實現從本機代碼到Java代碼的回調函數,我必須使用NewGloabRef創建全局引用。從內存配置文件中,我發現一旦我調用env->NewGlobalRef(weak_this),即使它是播放器對象的弱引用,Player對象也將作爲根對象提供,我認爲這會阻止它被垃圾收集。弱引用的NewGlobalRef仍然阻止垃圾收集對象

但我的理解是弱引用不會阻止垃圾收集對象。

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

WeakReference的是用普通參照它的Java對象。它包含對另一個對象的引用。它所包含的參考是「弱」的,而不是對WeakReference本身的提及。

因此,當您撥打env->NewGlobalRef(weak_this)(假設weak_thisWeakReference)時,其效果與將weak_this分配給靜態相同。它不會導致WeakReference包含的對象引用可以被強烈訪問。

我想你可能會誤解內存分析器告訴你什麼。特別是,我希望它顯示WeakReference包含的參考是可以達到的,直到GC決定斷開鏈接。在普通的static變量中嘗試使用WeakReference進行實驗。


UPDATE

我開始認爲這是JNI NewGlobalRef正常行爲。 JNI文檔(一如既往)對方法的行爲非常模糊。

請注意,還有一個名爲NewGlobalWeakRef的JNI方法;見http://java.sun.com/docs/books/jni/html/refs.html#27531。如果沒有別的,NewGlobalWeakRef提供了另一種做你正在做的事情的方式。

+0

Stephen,我在這裏添加了內存配置文件和JNI日誌。一旦我調用'NewGlobalRef','JniTPlayer'出現在根對象部分。而且,我在轉儲出內存配置文件之前強制GC。 – pierrotlefou 2011-05-31 09:58:59

+0

Stephen,NewGlobalWeakRef作品!謝謝! – pierrotlefou 2011-06-01 02:50:33