8

在重新加载上下文时,我们有多个 MemoryLeaks(在 catalina.out 中找到)。

为了清理这些线程,我创建了 ServletContextListener 的实现。

contextInitialized()创建上下文时成功调用该方法,因为我可以看到日志条目。

但是该contextDestroyed()方法没有被调用,所以我的清理代码没有被调用。任何想法为什么会发生这种情况?

当需要重新加载上下文时,我应该实现另一个需要注意的接口吗?

public class MyContextListener implements ServletContextListener {

    private static final Logger log = Logger.getLogger(MyContextListener.class);

    @Override
    public void contextDestroyed(final ServletContextEvent arg0) {
        MyContextListener.log.info("destroying Servlet Context");
        //Do stuff
        MyContextListener.log.info("Servlet Context destroyed");
    }

    @Override
    public void contextInitialized(final ServletContextEvent arg0) {
        try {
            MyContextListener.log.info("Creating Servlet Context");
            //Do stuff
        } finally {
            MyContextListener.log.info("Servlet Context created");
        }
    }
}
4

2 回答 2

1

我遇到了一些问题,我通过使用“修复”了它System.out.println

  @WebListener
  public class App implements ServletContextListener {
      private static final Logger logger = LoggerFactory.getLogger(App.class);

      @Override
      public void contextInitialized(ServletContextEvent sce) {
          System.out.println("START");
          logger.info("START");
      }

      @Override
      public void contextDestroyed(ServletContextEvent sce) {
          System.out.println("STOP");
          logger.info("STOP");
      }
  }

日志.txt:

[%thread] %-5level %logger{0}:%L - %msg%n
[localhost-startStop-1] INFO  App:16 - START

标准输出:

Commons Daemon procrun stdout initialized
START
STOP

这意味着contextDestroyed被调用,但记录器已经不起作用......我使用org.slf4j.Logger

要修复它,请参阅:Logging from servlet context destroy event

对不起,我的英语不好

于 2018-06-13T11:32:08.897 回答
0

据我所知,有几个问题:

  1. servlet 和过滤器在调用 contextDestroyed 之前被完全销毁,因此对于某些任务来说可能为时已晚。我不知道为什么 Tomcat 在调用此方法之前会报告潜在的内存泄漏。:-/
  2. 在调用此方法之前,类加载器似乎已被禁用(过滤器和 servlet 上的 destroy 方法可能也是如此?)这意味着如果您的 contextDestroyed 方法需要任何尚未加载的类,它将失败。:-(
于 2014-01-31T11:02:05.730 回答