java - 调试可能存在内存泄漏的tomcat应用程序

标签 java tomcat

情况 - API 应用程序在 tomcat 上运行。每次我到达 API 终点时,“top”中的内存使用量都会增加一小部分。当它通过 ~35-40%(大约十几个请求)后,负载水平从 1% 变为 40+%,并且应用程序变得无响应(并且必须重新启动 tomcat/容器)。

我做了什么:
1. 在 1 个请求后进行堆转储,然后在 5-10 个请求后进行堆转储并进行比较。内存增长不在我的任何类中,而是在“int[]”和“java.lang”中。我对java内存管理了解不够,无法理解这种情况。

  • 我使用 ps -eLf 监控线程计数/增长。没有什么可报告的。

  • 使用jstat -gc观察GC。输出如下所示:

  • (开始)

      S0C      S1C     S0U    S1U      EC       EU        OC         OU       MC      MU     CCSC   CCSU       YGC   YGCT    FGC    FGCT     GCT
      56832.0 57856.0  0.0   17266.5 157184.0 31716.8   546304.0   35573.4   40104.0 39112.5 4776.0 4474.5      7    1.669   2      0.251    1.921
    

    (结束 - 在我失去联系之前)

     S0C     S1C      S0U    S1U      EC       EU        OC         OU       MC       MU      CCSC     CCSU       YGC     YGCT  FGC      FGCT     GCT
     28160.0 27648.0  0.0    0.0   217088.0  4693.9   546304.0   76262.8   404008.0 402586.8 139816.0 139470.6     40    2.595  13      2.859    5.455
    
    • 再次 - 我对 java 内存管理了解不够,无法真正解释这些值。我可以看到主要的垃圾收集并没有花费太多时间,但肯定会发生。

    • 还尝试(作为冰雹玛丽)使用-XX:+UseG1GC。没有真正的区别。

    • 随着使用率值变得疯狂,我观察了 CPU %/IOWait(通过顶部)。 CPU保持理性并且没有可测量的IOWait。还查看了 top -H 和 wchan。

    还有其他值得一看的地方吗?看到这里明显被我忽略的东西了吗?

    使用 Java 8 运行。最新 Tomcat 版本。 CentOS 7。(在 Docker 中测试运行)。

    <小时/>

    附加

    使用jstat -class进行了一些测量,并对这些值感到好奇:

    (开始)

    Loaded  Bytes .   Unloaded  Bytes     Time
    121699 122371.1        4     3.4      31.34
    

    (完)

    Loaded  Bytes    Unloaded    Bytes    Time
    194495 191761.7        4     3.4      39.20
    

    这是否表明我的应用程序已加载额外的 70K 类并且未卸载任何类?这是一个问题吗?

    最佳答案

    使用 jvisualvm 并远程连接(通过使用正确的 jmx 参数 https://docs.oracle.com/javase/8/docs/technotes/guides/visualvm/jmx_connections.html 启动 Tomcat 实例)。然后您将能够看到所有内容,包括堆内存等等。在您的情况下,您可能会耗尽堆内存,GC 会继续尝试释放内存,但由于内存泄漏而无法这样做,并且这种情况会无限期地重复,CPU 非常繁忙。

    关于java - 调试可能存在内存泄漏的tomcat应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60005835/

    相关文章:

    tomcat - 为什么tomcat的应用程序没有结束斜线就不能运行?

    wordpress - Apache Tomcat 禁止连接到本地主机/~用户名

    Java 应用程序服务器替代品

    java - 如何通过使用 Selenium WebDriver 和 Java 从此 HTML 代码获取文本

    java - 相当于 Java 8::(双冒号)运算符的 Scala

    authentication - Tomcat JNDIRealm 验证异常

    bash - 在远程 tomcat 服务器上部署 ansible 和 bash

    Java BasicResponseHandler 异常

    java - 访问 BufferedImage 线程是否安全

    java - 如何定义整个spring项目的连接范围——web服务连接范围