Spring 启动 DelegatingSecurityContextAsyncTaskExecutor 导致潜在的内存泄漏
Spring boot DelegatingSecurityContextAsyncTaskExecutor causes potential memory leak
在 spring 启动应用程序 (2.1.4-RELEASE) 中使用以下任务执行器配置时
@Primary
@Qualifier("threadPoolTaskExecutor")
@Bean
public TaskExecutor threadPoolTaskExecutor() {
final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(100);
executor.setQueueCapacity(50);
executor.setThreadNamePrefix("Foo-");
executor.initialize();
return new DelegatingSecurityContextAsyncTaskExecutor(executor);
}
关闭时 tomcat (9.0.19) 我得到以下 warning.
02-May-2019 10:34:07.384 WARNUNG [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [myapp#bar] appears to have started a thread named [Foo-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.base@11.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@11.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:194)
java.base@11.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2081)
java.base@11.0.2/java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:433)
java.base@11.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1054)
java.base@11.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1114)
java.base@11.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
java.base@11.0.2/java.lang.Thread.run(Thread.java:834)
删除 DelegatingSecurityContextAsyncTaskExecutor 后 warning 消失:
@Primary
@Qualifier("threadPoolTaskExecutor")
@Bean
public TaskExecutor threadPoolTaskExecutor() {
final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(100);
executor.setQueueCapacity(50);
executor.setThreadNamePrefix("Foo-");
executor.initialize();
return executor;
}
这是什么原因?怎么解决?
更新: 对不起(请不要用石头砸我)但我完全忘记了它是一个 spring 启动应用程序,正在作为爆炸部署 war 在 tomcat 中。我现在也尝试了 tomcat 版本 9.0.17,它被 Spring 2.1.4.RELEASE 使用,但同样的问题。自行启动 spring 引导时,问题不会出现。
Update2:打开了一个bug
您需要为您的线程池执行器指定另一个名称。
您将设置归因于 Springs 默认线程池执行器,因此即使线程执行器上的 springs 现在也是异步的。
@Primary
@Qualifier("threadPoolTaskExecutor")
而是定义您自己的
@Primary
@Qualifier("appThreadPoolTaskExecutor")
Rob Winch 回答了 here。
在 spring 启动应用程序 (2.1.4-RELEASE) 中使用以下任务执行器配置时
@Primary
@Qualifier("threadPoolTaskExecutor")
@Bean
public TaskExecutor threadPoolTaskExecutor() {
final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(100);
executor.setQueueCapacity(50);
executor.setThreadNamePrefix("Foo-");
executor.initialize();
return new DelegatingSecurityContextAsyncTaskExecutor(executor);
}
关闭时 tomcat (9.0.19) 我得到以下 warning.
02-May-2019 10:34:07.384 WARNUNG [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [myapp#bar] appears to have started a thread named [Foo-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.base@11.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@11.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:194)
java.base@11.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2081)
java.base@11.0.2/java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:433)
java.base@11.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1054)
java.base@11.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1114)
java.base@11.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
java.base@11.0.2/java.lang.Thread.run(Thread.java:834)
删除 DelegatingSecurityContextAsyncTaskExecutor 后 warning 消失:
@Primary
@Qualifier("threadPoolTaskExecutor")
@Bean
public TaskExecutor threadPoolTaskExecutor() {
final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(100);
executor.setQueueCapacity(50);
executor.setThreadNamePrefix("Foo-");
executor.initialize();
return executor;
}
这是什么原因?怎么解决?
更新: 对不起(请不要用石头砸我)但我完全忘记了它是一个 spring 启动应用程序,正在作为爆炸部署 war 在 tomcat 中。我现在也尝试了 tomcat 版本 9.0.17,它被 Spring 2.1.4.RELEASE 使用,但同样的问题。自行启动 spring 引导时,问题不会出现。
Update2:打开了一个bug
您需要为您的线程池执行器指定另一个名称。 您将设置归因于 Springs 默认线程池执行器,因此即使线程执行器上的 springs 现在也是异步的。
@Primary
@Qualifier("threadPoolTaskExecutor")
而是定义您自己的
@Primary
@Qualifier("appThreadPoolTaskExecutor")
Rob Winch 回答了 here。