java - 调试可能存在内存泄漏的tomcat应用程序
问题描述
情况 - 在 tomcat 上运行的 API 应用程序。每次我到达 API 端点时,“top”中的内存使用量都会增加一小部分。在它通过 ~35-40%(大约十几个请求)后,负载水平从 1% 变为 40+%,并且应用程序变得无响应(并且必须重新启动 tomcat / 容器)。
我所做的:
1. 在 1 个请求和 5-10 个请求后进行堆转储并比较这些。内存增长不在我的任何课程中,而是在“int []”和“java.lang”中。我对 java memory mgmt 的了解还不够,无法理解这种情况。
我使用
ps -eLf
. 没有什么可报告的。使用
jstat -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 memory mgmt 的了解不够,无法真正解释这些值。我可以看到主要的垃圾收集并没有花费太多时间,但肯定会发生。
还尝试(作为冰雹)使用
-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 非常繁忙。
推荐阅读
- python - 从 Poppler 导入版本时 DLL 加载失败
- c++ - 是否有充分的理由在新代码中使用“extern”链接说明符?
- javascript - 尝试使用节点 js 更新 mongodb 中的单个条目
- sharepoint - 如何在 Hub 站点 Sharepoint Online 的西装栏导航中更改站点名称
- reactjs - React - toggleClass on button 激活所有按钮
- google-analytics - 使用 Google Analytics 时,您是否必须为您的网站编制索引?
- javascript - 如何在 moment.js 中更改语言环境
- javascript - 如何为字符串的特定部分添加 HTML 标记(javascript)
- html - CSS:在 div 后面居中视频而不影响整体 div 布局?
- java - 地图
在 java 中的 @ConfigurationProperties 的 yaml 文件中?