Guice 3.0 + Tomcat 7.0 = ClassLoader memory leak

后端 未结 1 1834
长发绾君心
长发绾君心 2020-12-30 08:25

I know that this problem has been around for at least 3 yeears (Issue 92), but I\'m still not satisfied with the current state of it. I am also aware that this does not affe

相关标签:
1条回答
  • 2020-12-30 09:11

    Well, no one was there to help me, so here's what I learned:

    The Finalizer thread is started by the FinalizableReferenceQueue (FRQ). There is a hard (static) reference to the FRQ in MapMaker. The WebAppClassLoader was not garbage collected because MapMaper was still around due to the hard reference.

    The following code solved my problem:

    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);
    

    Here's the offending code (com.google.inject.internal.util.MapMaker):

    /** Wrapper class ensures that queue isn't created until it's used. */
    private static class QueueHolder {
      static final FinalizableReferenceQueue queue = new FinalizableReferenceQueue();
    }
    

    After doing this, the Finalizer thread gracefully dies.

    0 讨论(0)
提交回复
热议问题