2010-08-17 66 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