首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >安卓FinalizerDaemon挂机

安卓FinalizerDaemon挂机
EN

Stack Overflow用户
提问于 2016-05-03 18:03:18
回答 1查看 5.3K关注 0票数 19

我在一个Android应用程序中遇到了一个非常奇怪的问题。在某个时间点之后(大约在主活动开始并显示片段的时候),FinalizerDaemon就会停止处理对象,垃圾继续堆积。看一下线程转储,它似乎被ReferenceQueue.remove()卡住了:

"FinalizerDaemon@4461" daemon prio=5 waiting
  java.lang.Thread.State: WAITING
      at java.lang.Object.wait(Object.java:-1)
      at java.lang.Object.wait(Object.java:423)
      at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:101)
      - locked <0x1173> (a java.lang.ref.ReferenceQueue)
      at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:72)
      at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:185)
      at java.lang.Thread.run(Thread.java:818)

然而,队列并不是空的。如果我在使用app一段时间后转储堆,队列实际上有数千个条目那么长。数据结构看起来也没有损坏:

在分配和垃圾收集之后再次转储表明队列的头部是与之前相同的Matrix实例。

现在,我注意到了这一点,因为我保留了一些C++对象,这些对象需要在某个时候释放。虽然我怀疑终结器调用JNI函数并在C++端做一些愚蠢的事情可能会以某种方式破坏它,但我的所有日志都表明,所有终结器都运行得很好,并且返回时没有抛出任何东西,直到它们被随机停止调用。此外,finalize调用不应该真的破坏守护进程,除非分割整个应用程序或其他什么,因为Watchdog应该处理运行太长时间并抛出异常的终结器。

我尝试了一个显式的System.runFinalization(),它所做的就是永远挂起主线程,等待永远不会运行的守护进程。

知道这是怎么发生的吗?

EN

回答 1

Stack Overflow用户

发布于 2016-07-21 18:38:06

我相信这与一些对象在他们的resurrected方法中是finalize有关。

我将引用这篇question中的一段。

终结器线程运行,以便垃圾收集操作来清理与对象关联的资源。如果我没看错的话,终结器不能获得这个对象的锁: java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118),因为 java对象正在运行一个方法,所以终结器线程被锁定,直到该对象完成了它的当前任务。

也许这就是你所处的情况。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37001181

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档