Ответ 1
Ну, никто не был там, чтобы помочь мне, поэтому вот что я узнал:
Нить Finalizer запускается FinalizableReferenceQueue (FRQ). Существует жесткая (статическая) ссылка на FRQ в MapMaker. WebAppClassLoader не собирался сбор мусора, потому что MapMaper все еще был вокруг из-за жесткой ссылки.
Следующий код решил мою проблему:
final Class<?> queueHolderClass =
Class.forName("com.google.inject.internal.util.$MapMaker$QueueHolder");
final Field queueField = queueHolderClass.getDeclaredField("queue");
// make MapMaker.QueueHolder.queue accessible
queueField.setAccessible(true);
// remove the final modifier from MapMaker.QueueHolder.queue
final Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(queueField, queueField.getModifiers() & ~Modifier.FINAL);
// set it to null
queueField.set(null, null);
Здесь код нарушения (com.google.inject.internal.util.MapMaker
):
/** Wrapper class ensures that queue isn't created until it used. */
private static class QueueHolder {
static final FinalizableReferenceQueue queue = new FinalizableReferenceQueue();
}
После этого поток Finalizer изящно умирает.