Android FinalizerDaemon 挂断
2022-09-02 14:09:00
我在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)
然而,队列不是空的。如果我在使用应用程序一段时间后转储堆,则队列实际上有数千个条目。数据结构看起来也没有损坏:
在分配和垃圾回收之后再次转储,表明队列的头部与以前是相同的矩阵实例。
现在,我注意到了这一点,因为我保留了一些C++对象,这些对象需要在某个时候释放。虽然我怀疑调用JNI函数并在C++端做一些愚蠢的事情的终结器可能会以某种方式破坏它,但我的所有日志都表明所有终结器都运行良好,并且在没有抛出任何东西的情况下返回,直到它们随机停止被调用。此外,最终确定调用应该不可能破坏守护进程,除非对整个应用程序或其他内容进行隔离,因为监视程序应该处理运行时间过长并引发异常的终结器。
我尝试了一个显式的,它所做的就是永远挂起主线程,等待永远不会运行的守护进程。System.runFinalization()
任何想法怎么会发生这种情况?