我仍然在tomcat/logs/catalina.out中看到这个错误。
Dec 29, 2011 4:04:36 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/LoggingMonitor] appears to have started a thread named [Timer-1] but has failed to stop it. This is very likely to create a memory leak.
Dec 29, 2011 4:04:36 PM org.apache.coyote.http11.Http11Protocol destroy
INFO: Stopping Coyote HTTP/1.1 on http-8180这是否值得考虑?如果是的话,我该如何纠正?
发布于 2011-12-30 17:25:20
这可能没什么大不了的(就是kill -9之类的),而且很容易修复。只需找出在/LoggingMonitor上下文中运行的for应用程序,然后grep其代码库...
new Timer();...and将它们全部替换为...
new Timer( true );默认情况下,java.util.Timer不在守护程序线程中运行。您需要在webapp中使用任何计时器才能在守护程序线程上运行(否则容器将无法正常关闭,因为它正在等待计时器线程结束,而这永远不会结束)。找到所有的"new Timer()“调用,并将它们替换为"new Timer( true )”,日志记录投诉应该会停止。
花点时间在JavaDocs中学习一些关于守护进程与非守护进程线程的知识:http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Timer.html
当我在webapps中工作时,如果我结束了我自己的多线程,我总是使用守护线程。有了java.util.concurrent中的工具,这变得非常罕见(我必须自己做线程工作)。
最后,我要郑重声明,我讨厌java.util.Timer,并且总是推荐使用像ScheduledExecutor这样的东西来完成周期性、重复性的任务。它太容易搞砸计时器,并拿出它执行的踏步,守护进程或其他。
发布于 2014-04-28 16:27:42
如果你总是在取消部署/重新部署应用程序时停止Tomcat,那么这条消息并不是什么大问题,否则这些操作会导致内存泄漏,这是一个大问题,特别是在生产中。
根据Bob Kuhar的建议,名为"Timer-#“的线程是由java.util.Timer创建的(也可能是由其他类创建的),但是使用您自己的代码库是不够的,并且确保您使用守护线程并不能消除该消息( Tom Hawtin的评论是正确的)。
当我收到这条消息时,它是由我的代码的传递依赖项生成的,确切地说是由使用守护程序线程的Apache Commons Poolv1.3的GenericObjectPool类生成的(请参阅source code)。为了找到实例化Timer的类,我必须在每个Timer类的构造函数中放置一个断点,然后检查调用堆栈。为了解决这个问题,我不得不升级这个库( Commons Pool的新版本不使用该计时器)。
当您能够控制实例化线程的代码时,可以通过确保在应用程序停止时停止线程来解决此问题。使用守护程序线程是一个很好的实践,但这还不够,因为只有在关闭Tomcat时,守护程序线程才会自动终止,而在取消部署应用程序时,守护程序线程不会自动终止。
在更一般的情况下,当您不知道是谁创建了讨厌的线程时,可以检查Finding Source of Thread Creation in a Java application和Detect Who Created a Thread (w. Eclipse)。
更新
一种完全不同的方法是使用非常有趣的Leak Prevention Listener。也请阅读该作者撰写的有关类加载器泄漏的其他文章。
https://stackoverflow.com/questions/8677008
复制相似问题