У меня очень странная проблема в Android-приложении. После определенного момента (вокруг, когда начинается основная активность и отображается фрагмент) FinalizerDaemon просто прекращает обработку объектов, а мусор продолжает накапливаться. Если посмотреть на дамп потока, он, похоже, застрял на ReferenceQueue.remove()
:
"[email protected]" 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)
Но очередь не пуста. Если я сбрасываю кучу после использования приложения некоторое время, очередь составляет буквально тысячи записей. Структура данных также не выглядит разбитой:
Сброс снова после выделения и удаления мусора еще несколько показывает, что глава очереди - это тот же экземпляр матрицы, что и раньше.
Теперь я заметил это, потому что я сохраняю некоторые объекты на С++, которые нужно в какой-то момент выпустить. Хотя я подозреваю, что финализатор, вызывающий функции JNI и делающий что-то глупое на стороне С++, может как-то сломать его, все мои журналы показывают, что все финализаторы работают нормально и возвращаются, не бросая ничего, пока они просто случайно не перестанут получать вызов. Кроме того, не должно быть действительно возможно, чтобы завершить вызов для разрыва Демона, не выполнив segfaulting всего приложения или что-то еще, поскольку Watchdog должен обрабатывать финализаторы, которые работают слишком долго и генерируют исключение.
Я попробовал явный System.runFinalization()
, и все, что он делает, вечно вешает основной поток, ожидая, что демон не будет работать.
Любая идея, как это могло произойти?