Android FinalizerDaemon hanging up
I’m having a really weird problem in an Android app. After a certain point (around when the main activity starts and a fragment is displayed) the FinalizerDaemon just stops processing objects and garbage keeps piling up. Looking at a thread dump, it seems to be stuck on
"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)
Yet the queue is not empty. If I dump the heap after using app for a while, the queue is literally thousands of entries long. The data structure also doesn’t look broken:
Dumping again after allocating and garbage collecting some more shows that the head of the queue is the same Matrix instance as before.
Now, I noticed this because I’m retaining some C++ objects, which need to be released at some point. While I suspect that a finalizer calling into JNI functions and doing something stupid on the C++ side could somehow break it, all my logs indicate that all the finalizers are running fine and returning without throwing anything until they just randomly stop getting called. Also, it shouldn’t really be possible for a finalize call to break the Daemon, short of segfaulting the whole app or something, since the Watchdog is supposed to handle finalizers that run for too long and throw an exception.
I tried an explicit
System.runFinalization() and all it does is hang the main thread forever, waiting for the daemon which never runs.
Any idea how this could happen?
One Solution collect form web for “Android FinalizerDaemon hanging up”
I believe this has to do with some objects being resurrected in their finalize methods.
I’ll quote a paragraph from this question.
The finalizer thread runs so the garbage collection operates to clean
up resources associated with an object. If I’m seeing it corectly, the
finalizer can’t get the lock to this object:
the java object is running a method, so the finalizer thread is locked
until that object is finished with it’s current task.
Maybe that’s the situation you have.