我正在使用 Spring Boot 1.5.9.RELEASE + Java 8 + Tomcat 9 + Jersey + Oracle 并且我的应用程序已计划方法定义如下:
@Configuration
@EnableScheduling
public class ScheduleConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
}
@Bean(destroyMethod = "shutdown")
public Executor taskExecutor() {
return Executors.newScheduledThreadPool(100);
}
}
工作类别:
@Component
public class ClearCacheJob {
@Scheduled(fixedRate = 3600000, initialDelay = 10000)
public void clearErrorCodesCache() {
try {
logger.info("######## ClearCacheJob #########");
} catch (Exception e) {
logger.error("Exception in ClearCacheJob", e);
}
}
}
我还有一个类来注销 Oracle 驱动程序,如下所示:
@WebListener
public class ContainerContextClosedHandler implements ServletContextListener {
private static final Logger logger = LoggerFactory.getLogger(ContainerContextClosedHandler.class);
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
logger.info("######### contextInitialized #########");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
logger.info("######### contextDestroyed #########");
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
try {
DriverManager.deregisterDriver(driver);
logger.info(String.format("deregistering jdbc driver: %s", driver));
} catch (SQLException e) {
logger.info(String.format("Error deregistering driver %s", driver), e);
}
}
}
}
但是在停止 Tomcat 时出现以下错误:
WARNING [Thread-11] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [hai]
appears to have started a thread named [Timer-0] but has failed to stop it.
This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
java.lang.Object.wait(Unknown Source)
java.util.TimerThread.mainLoop(Unknown Source)
java.util.TimerThread.run(Unknown Source)
为什么会出现此错误,我该如何解决?
原文由 Mahmoud Saleh 发布,翻译遵循 CC BY-SA 4.0 许可协议
我想与此问题的根本原因分析分享一些解决方案。
解决方案 #1
您应该从 Tomcat 的
/lib
文件夹中删除 Oracle 驱动程序。我遇到了同样的问题,它得到了解决。注意: 让 Oracle 驱动程序位于
/WEB-INF/lib
文件夹中。解决方案#2
您可以通过休眠线程使用真正的 hack。
资源链接: “Tomcat can’t stop [Abandoned connection cleanup thread]”的解决方案
解决方案#3
斯维特林·扎列夫 ( Svetlin Zarev ) 表示无需担心。这是tomcat的标准消息。他给出了如下根本原因分析:
资源链接: Tomcat8 内存泄漏
解决方案#4
对于 Oracle 用户,这篇文章中有多个答案: To prevent a memory leak, the JDBC Driver has been forcingly unregistered
解决方案#5
根本原因分析及解决方案:
资源链接: https ://docs.oracle.com/cd/E17952_01/connector-j-relnotes-en/news-5-1-23.html