Catalina.out Memory leak error

前端 未结 2 798
孤城傲影
孤城傲影 2021-01-19 19:01

I still see this error in tomcat/logs/catalina.out.

Dec 29, 2011 4:04:36 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
         


        
相关标签:
2条回答
  • 2021-01-19 19:36

    That message is not a big deal if you always stop Tomcat when you undeploy/redeploy your app otherwise these operations cause a memory leak that is a big deal, expecially in production.

    Threads named "Timer-#" are created by java.util.Timer (and maybe by other classes) as suggested by Bob Kuhar but grepping your own codebase could be not enough and ensuring that you use daemon threads doesn't eliminate that message (the comment by Tom Hawtin is correct).

    When I got that message it was produced by a transitive dependency of my code, precisely by class GenericObjectPool of Apache Commons Pool v1.3 that uses a daemon thread (see source code). To find the class that instantiates the Timer I had to put a breackpoint in each Timer class' constructor and then I examined the call stack. To solve the issue I had to upgrade the library (newer versions of Commons Pool don't use that Timer).

    When you have control over the code that instantiates the thread you can solve the issue by ensuring that you stop the thread when the application stops. Using daemon threads is a good practice but is not enough because daemon threads die automatically only when you shutdown Tomcat but not when you undeploy the application.

    In a more general case, when you have no idea about who created the nasty thread, check Finding Source of Thread Creation in a Java application and Detect Who Created a Thread (w. Eclipse).

    UPDATE

    A completely different approach is to use the very interesting Leak Prevention Listener. Also read the other posts about classloader leaks by that author.

    0 讨论(0)
  • 2021-01-19 19:37

    This is probably no big deal (just kill -9 or something) and easy enough to fix. Just figure out which webapp in running on a context of /LoggingMonitor then grep its codebase for...

    new Timer();
    

    ...and replace them all with...

    new Timer( true );
    

    java.util.Timer by default does not run in daemon threads. You need any Timers in your webapps to run on daemon threads (otherwise the container is unable to shutdown properly as it is waiting for the Timer thread to end, which it never does). Find all the "new Timer()" calls and replace them with "new Timer( true )" and the logging complaint should stop.

    Spend some time in the JavaDocs learn something about daemon vs non daemon Threads: http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Timer.html

    When I'm working in webapps, I always use daemon threads if I end up doing any of my own multithreading. With the facilities in java.util.concurrent, this is becoming very rare (having to do my own Threading stuff).

    Finally, and for the record, I hate java.util.Timer and always recommend using something like ScheduledExecutor to do periodic, repetitive tasks. Its too easy to screw up in Timer and take out the Tread it executes on, daemon or otherwise.

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