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