Android FinalizerDaemon挂断了

Ivo*_*lov 19 java multithreading android android-ndk android-runtime

我在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)
Run Code Online (Sandbox Code Playgroud)

但队列并非空.如果我在使用app一段时间之后转储堆,那么队列实际上是数千个条目.数据结构也看起来不破: FinalizerDaemon实例显示非空的ReferenceQueue

在分配和垃圾收集后再次转储更多显示队列的头部与以前相同的Matrix实例.

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

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

知道怎么会这样吗?

Min*_*amy 2

我相信这与某些对象在其 Finalize 方法中复活有关。

我将引用这个问题中的一段话。

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

也许这就是你的情况。