我有一个Android活动和一个使用aidl实现的服务。像冠军一样工作,我有一个回调设置将一些线程通知传递回UI,并且看起来工作正常,除了很多
GREF已增加到101,201,301,401,501等,GREF已减少。我做了一些在线搜索,发现它必须做全球参考。
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和垃圾收集的影响..
答案 0 :(得分:18)
这些是JNI全球参考。如果您不编写本机代码,则无法直接控制它们。启用CheckJNI时会显示日志消息,默认情况下对于工程版本和模拟器启用。
消息只是意味着本机代码告诉VM不允许丢弃某些对象。本质上,全局引用是本机代码添加对GC根集的引用的一种方式。假设本机代码写得正确,当本机代码不再需要时,全局引用将被清除。
唯一值得关注的问题是全球参考数量是否继续攀升,因为这表明全球参考泄漏。由于VM无法释放对象,因此全局ref泄漏最终会导致VM耗尽内存。为了帮助识别这些问题,当启用CheckJNI时,会对全局引用的数量设置上限(当前限制为2000)。