Tomcat修复内存泄漏?

时间:2013-07-29 16:10:53

标签: java tomcat memory memory-leaks

我正在使用6.0.20我在服务器上运行了许多Web应用程序,随着时间的推移,大约需要3天,服务器需要重新启动,否则服务器崩溃并变得无法响应。

我对JVM有以下设置:

-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=c:\tomcat\Websites\private\mydomain\apache-tomcat-6.0.20\logs

这为我提供了一个hprof文件,我使用Java VisualVM加载了该文件,该文件标识了以下内容:

byte[] 37,206   Instances | Size 86,508,978
int[] 540,909   Instances | Size 55,130,332
char[] 357,847  Instances | Size 41,690,928

列表继续,但我如何确定导致这些问题的原因?

我正在使用New Relic监视JVM,似乎只出现了一个错误,但它是一个重复发生的错误,org.apache.catalina.connector。 ClientAbortException。是否有可能在用户会话中止时,创建的所有数据库连接或变量都没有被关闭,因此会成为孤立状态?

在每个网络应用程序中都有一个功能被大量使用,不确定这是否与泄漏有关:

public static String replaceCharacters(String s)
{
    s = s.replaceAll("  ", " ");
    s = s.replaceAll(" ", "_");
    s = s.replaceAll("\351", "e");
    s = s.replaceAll("/", "");
    s = s.replaceAll("--", "-");
    s = s.replaceAll("&", "and");
    s = s.replaceAll("&", "and");
    s = s.replaceAll("__", "_");
    s = s.replaceAll("\\(", "");
    s = s.replaceAll("\\)", "");
    s = s.replaceAll(",", "");
    s = s.replaceAll(":", "");
    s = s.replaceAll("\374", "u");
    s = s.replaceAll("-", "_");
    s = s.replaceAll("\\+", "and");
    s = s.replaceAll("\"", "");
    s = s.replaceAll("\\[", "");
    s = s.replaceAll("\\]", "");
    s = s.replaceAll("\\*", "");
    return s;
}

是否可能在用户连接中止时,例如用户浏览器关闭或用户离开网站,所有变量,连接等都被清除/释放,但不是GC假设处理那个?

以下是我的JVM设置:

-Dcatalina.base=c:\tomcat\Websites\private\mydomain\apache-tomcat-6.0.20
-Dcatalina.home=c:\tomcat\Websites\private\mydomain\apache-tomcat-6.0.20
-Djava.endorsed.dirs=c:\tomcat\Websites\private\mydomain\apache-tomcat-6.0.20\endorsed
-Djava.io.tmpdir=c:\tomcat\Websites\private\mydomain\apache-tomcat-6.0.20\temp
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Djava.util.logging.config.file=c:\tomcat\Websites\private\mydomain\apache-tomcat-6.0.20\conf\logging.properties
-Dfile.encoding=UTF-8
-Dsun.jnu.encoding=UTF-8
-javaagent:c:\tomcat\Websites\private\mydomain\apache-tomcat-6.0.20\newrelic\newrelic.jar
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=c:\tomcat\Websites\private\mydomain\apache-tomcat-6.0.20\logs
-Dcom.sun.management.jmxremote.port=8086
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false vfprintf
-Xms1024m
-Xmx1536m

我错过了什么吗?服务器有3GB内存。

非常感谢任何帮助: - )

3 个答案:

答案 0 :(得分:2)

  

...但我如何确定导致这些问题的原因?

您需要使用转储分析器,以便查看使这些对象可以访问的内容。选择一个对象,然后查看其他对象或对象引用它...并通过链向后工作,直到找到“GC根”或您识别的某个特定于应用程序的类。

以下是分析内存快照和内存分析器的几个参考资料:

一旦确定了这一点,您就已经完成了识别存储泄漏源的大部分工作。


该功能与泄漏没有直接关系。它肯定不会导致它。 (它可能会生成大量垃圾String对象......但这是一个不同的问题。)

答案 1 :(得分:2)

我将所有项目迁移到Tomcat 7.0.42并且我的错误已经消失,我们的网站更稳定,速度更快,我们使用的内存更少,CPU使用率更高。

答案 2 :(得分:0)

在本地开发环境中启动服务器,附加探查器(最好是你的套件),定期进行堆转储,你会看到对象byte []的增长,你可以实际将那些byte[]与你的应用程序类连接起来这个工具可以帮助你识别代码中的缺陷