2010-08-17 15 views
7

我有一個android活動和一個使用aidl實現的服務。像冠軍一樣工作,我有一個回調設置,將一些線程通知傳遞迴UI,並且似乎工作正常,除了很多GREF在多線程服務中增加/減少(aidl) - 這意味着什麼?

GREF已增加到101,201,301,401,501等等,而GREF已經下降。我在網上做了一些搜索,發現它必須做w/Global References。

08-17 02:31:19.735: DEBUG/dalvikvm(2558): GREF has increased to 301 
... 
08-17 02:31:25.823: DEBUG/dalvikvm(2558): GREF has increased to 401 
... 
08-17 02:31:36.772: DEBUG/dalvikvm(2558): GREF has increased to 501 
... 
08-17 02:31:42.694: DEBUG/dalvikvm(2558): GREF has increased to 601 
... 
08-17 02:31:48.695: DEBUG/dalvikvm(2558): GREF has increased to 701 
... 
08-17 02:31:59.883: DEBUG/dalvikvm(2558): GREF has decreased to 599 
08-17 02:31:59.912: DEBUG/dalvikvm(2558): GREF has decreased to 499 
08-17 02:31:59.912: DEBUG/dalvikvm(2558): GREF has decreased to 399 
08-17 02:31:59.912: DEBUG/dalvikvm(2558): GREF has decreased to 299 
08-17 02:31:59.912: DEBUG/dalvikvm(2558): GREF has decreased to 199 

我做了一些搜索,看到對此的大部分評論都比較陳舊。我擔心的是我正在正確地實施我的客戶/服務,並想知道我如何能夠追蹤導致GREF增加的原因。任何想法/建議都歡迎。謝謝!

基本程序流

Client -> Creates Callback 
Client -> Starts Service 
Service -> Inits & Starts CountDownTimer 
Service.CountDownTimer.onFinish() -> DownloadAndParse() 
DownloadAndParse() -> initialize new saxRequest(), new Handler for this request. 
Service.Handler->beginBroadcast() 
Client.CallbackStub -> updateUI() 
Client.CallbackStub -> service.startCountDownTimer() 

希望這是有道理的。我會在這裏發佈代碼,但是在很多不同的文件中都有這麼多。我想我會試着把流量放在一起,看看有沒有什麼明顯的...我能看到的唯一可能是重新使用saxRequest()而不是創建一個新的實例...我現在會嘗試,但我真的很想知道GREF和垃圾收集的影響。

回答

18

這些是JNI全局參考。如果你不寫本地代碼,你不能直接控制它們。當啓用CheckJNI時,會出現日誌消息,默認情況下,工程構建和模擬器處於啓用狀態。

這些消息只是表示本機代碼正在告訴虛擬機不允許丟棄某些對象。實質上,全局引用是本機代碼添加對GC根集的引用的一種方式。假設本地代碼編寫正確,當本地代碼不再需要它們時,全局引用將被清除。

如果全球裁判人數繼續攀升,唯一值得關注的原因是因爲這意味着全球參考泄漏。由於虛擬機無法釋放這些對象,全局引用泄漏最終會導致虛擬機內存不足。爲了幫助識別這些問題,當啓用CheckJNI時(當前限制爲2000),將在全局引用的數量上設置一個上限。

+2

非常感謝。我實際上即將開始編寫一些JNI代碼,因此瞭解這一點將有所幫助,以前從未注意到它。奇怪的是,第一次看到某些東西需要兩年的時間。非常感謝,你回答了我的問題。 – Chrispix 2010-08-18 05:26:28