【问题标题】:Leak memory in war servlet with tomcat使用tomcat在war servlet中泄漏内存
【发布时间】:2014-03-21 09:12:31
【问题描述】:

当我尝试在我的工作 servlet 中实现一个新功能时遇到了一些问题。

现在我有一个 servlet,手机可以在其中注册。手机使用 rest 来注册这个 servlet。它工作完美。每当您尝试注册电话时,它都会起作用。

但是现在,我需要添加一个新功能。我想将此服务器注册到我的基础架构的其他组件。

我希望一开始就完成注册。我的意思是,当 servlet 启动时,进行注册并忘记它,就像以前一样工作。

这是tomcat给我的错误:

Grave: The web application [/servletRegister] appears to have started a thread named [Timer-8] but has failed to stop it. This is very likely to create a memory leak.

这是我的开始课程:

@Override
public Set<Class<?>> getClasses() {
    //-------------------------------
    //Set registration here
    //GatewayRegistrationHandler reg = GatewayRegistrationHandler.getInstance(); 
    //reg.registerDevice();
    //-------------------------------
    //register on a new thread due to process time      
    new Thread (new RegisterGatewayOnBackground()).start();

    //Next are the working servlet code
    Set<Class<?>> classes = new HashSet<Class<?>>();
    classes.add(PublicationsResource.class);  /
    classes.add(DeviceResource.class);
    return classes;
}

}

我首先尝试了注释行。然后我遇到了内存泄漏,我试图在一个新线程中执行它们以避免泄漏。但是行为是一样的。

后台功能是这样的:

public class RegisterGatewayOnBackground implements Runnable {
    public RegisterGatewayOnBackground() {
    }   
    public void run() {
        registerDevice();
    }
    private void registerDevice() {         
          GatewayRegistrationHandler reg = GatewayRegistrationHandler.getInstance(); 
          reg.registerDevice();   
    }
}

GatewayRegistrationHandler 工作正常,因为当我运行 servlet 时,它会执行、进行注册,然后崩溃。我认为这是一个时间问题,背景会解决它,但我被困在这里,因为背景也是如此。

我不知道有什么方法可以检查哪里可以找到我的内存泄漏。我正在寻找可以帮助我解决问题的建议或任何工具。

【问题讨论】:

  • 这是java代码,什么内存泄漏?垃圾收集器确保没有内存泄漏。为什么说可能是这样?
  • 因为 tomcat 日志:catalina.2014... 说这个 servlet 由于内存泄漏而关闭。我也认为垃圾收集器应该删除所有未使用但...
  • @Pandrei:GC 无法确保没有内存泄漏。它只会有帮助。
  • 您能否从您的日志文件中粘贴相关行。另外,是tomcat自行关闭还是在您尝试关闭tomcat时显示此消息?
  • @Biribu 这根本不是错误所说的。它说可能存在内存泄漏,因为(计时器)线程已启动,但在请求完成时并未停止。我也没有看到任何证据表明它实际上是一个错误,它似乎只是一个警告消息。

标签: java servlets memory-leaks tomcat6


【解决方案1】:

当你这样启动你的线程时,它不会被命名为“Timer-x”。因此,这可能是从其他地方开始的线程。

tomcat 给你的消息表明 webapp 正在以某种方式被取消部署(然后它会检查仍然存在的线程,如果有则抱怨)。我不确定为什么会发生取消部署,但如果是因为您正在停止 webapp。,除非您进行(大量)热部署(在保持 tomcat 运行的同时进行部署和取消部署),否则您可能不需要修复此问题。这是因为,如果它在您无论如何要终止进程之前泄漏内存,则内存泄漏不会有任何危害,并且修复它会浪费时间。

如果您想修复它,一种简单的方法是挂钩分析器并查看谁启动了这个“计时器”线程。

【讨论】:

  • 每次我对代码进行更改时,我都会在重新部署之前取消部署我的应用程序。我该怎么做?重新部署而不取消部署正在运行的实例?
  • @Biribu:最简单的方法是执行“冷部署”,完全杀死 tomcat,然后复制新工件并启动 tomcat。无论如何,这通常建议用于生产部署。但是出于开发目的,您可以像现在一样继续进行热部署,并且仅在进程无法再进行泄漏时才进行冷部署(变得超级慢,由于内存不足错误等而死)
猜你喜欢
  • 2014-12-25
  • 1970-01-01
  • 2011-04-18
  • 2012-08-20
  • 2015-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-15
相关资源
最近更新 更多