【问题标题】:Why tomcat increase always memory usage and never free it?为什么tomcat总是增加内存使用量而从不释放它?
【发布时间】:2020-05-02 22:35:54
【问题描述】:

我有一个带有 tomcat 的 Unix 服务器,里面有一个 webapps。

如果我执行 free -h 我查看大约 50% 已使用: 使用顶级命令: 我查看了这个过程:

 21603 azureus+  20   0 7816556 1.104g  18200 S   0.0  45.1   0:36.41 


    /usr/lib/jvm/java-8-oracle/bin/java -Djava.util.logging.config
.file=/home/azureuser/tomcat/apache-tomcat-9.0.8/conf/logging.properties -Djava.util.loggi
ng.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.
protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.Secu
rityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /home/azureuser/tomcat/apache-t
omcat-9.0.8/bin/bootstrap.jar:/home/azureuser/tomcat/apache-tomcat-9.0.8/bin/tomcat-juli.j
ar -Dcatalina.base=/home/azureuser/tomcat/apache-tomcat-9.0.8 -Dcatalina.home=/home/azureu
ser/tomcat/apache-tomcat-9.0.8 -Djava.io.tmpdir=/home/azureuser/tomcat/apache-tomcat-9.0.8
/temp org.apache.catalina.startup.Bootstrap start

使用 45% 的内存。

我想了解是我在 myprojects 中的代码的问题还是 TOMCAT 的问题。 我的应用是一个带有 2 个控制器的 springboot 应用:

这里是代码:https://pastebin.com/yq5F0XTG

我有两个功能:

  • 由使用 URLClassLoader 的 requestController ->getTestList() 调用的 getAllTests 但我最后用以下命令关闭它:

    child.close();
    j.close() <--for JarFile that I load
    child=null;
    System.gc()
    
  • requestController 调用的runOne -> runTest() 也在这里它使用 ClassLoader 但我最后用以下方式关闭它:

    loader=null;
    System.gc();
    

    当我调用 getTestList() 并使用 top 监视内存时,我认为 TOMCAT 实例将内存使用量从 13.2 增加到 13.7,但最终它并没有减少。 同样随着 runTest() 内存增加,但在方法 runOne() 结束后它不会减少..

多次调用控制器功能后,我的内存出现问题(60-70% 的使用率)。

是tomcat配置问题还是我的代码问题?

PS:我无法在 unix 服务器上安装任何东西,因为我没有权限 root 并且 VisualVM 不能在我的 Windows 本地机器上工作...

请帮帮我。

感谢大家的任何提示..

【问题讨论】:

    标签: tomcat memory-management classloader


    【解决方案1】:

    除非在当前 JVM 中发生了我不知道的更改:JVM 不会为操作系统释放内存,如果它不使用它:它将释放 em>它自己的 堆,但您在启动时对其进行了配置,最多允许-Xmx 内存。这就是它所需要的(加上一些)。

    如果您的应用程序可以使用更少的内存:更改该配置。但是,一旦超出该内存,您的 JVM 就会以 OutOfMemory 条件终止。

    明智地选择该配置,并牢记:您已明确允许 JVM 使用该内存量。如果它占用了您的津贴,请不要感到困惑。

    在生产系统中,我通常将 -Xmx 设置为等于 -Xms 以确保 JVM 在启动时获取所有内存,而不是在周末晚上无法从操作系统分配更多内存,从而在我不这样做时导致失败不想被提醒。

    【讨论】:

    • 您好,感谢您的回答,所以您的问题是 Tomcat 设置不在我的代码中吗?如果这是真的,那么我会将此传达给 unix 系统管理员。你确定?我在网上读到 ClassLoader 在我调用它后没有释放内存.. 但我不确定
    • 您应该检查 JVM 自己的堆以确保再次释放 JVM 中的内存。但我认为这是正常操作,JVM 从不 将内存释放回操作系统。您所描述的内容并未暗示您的应用程序内存泄漏,但也不能排除。
    • ok 那么如何在tomcat中设置-Xmx和Xms内存限制呢?在这个服务器中,我认为这两个选项没有设置,因此很长一段时间后会填满整个内存..
    • 在哪里配置呢?这取决于您的实施。我见过的最标准的位置是在 tomcat 的 bin/setenv.sh 中(您必须自己创建一个文件)。它通常是一些用于启动 tomcat 的 shellscript。在 Windows 上,如果将 tomcat 作为服务安装,它在服务配置中(通常在安装服务时设置)。 JVM 不太可能用完所有内存 - 它们有一个默认限制,您需要明确覆盖它才能使用大量内存。
    • 啊,好的,谢谢.. 所以对你来说 classLoader 不是问题吗?
    猜你喜欢
    • 1970-01-01
    • 2014-02-10
    • 1970-01-01
    • 2017-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-14
    • 2014-07-11
    相关资源
    最近更新 更多