我在基于 Java servlet 的服务器(在 WebLogic 12 和 Oracle Enterprise Linux 下运行的 Java 1.7)上执行了 12 小时的负载测试。测试结束后,我观察到内存消耗逐渐从测试开始时的 500Mb 上升到 3.5Gb 左右(并在几个小时内波动+/- 500Mb)。 3 天后(服务器在这 3 天内没有执行任何操作)- 我再次检查内存,发现这 3.5Gb 中没有任何内容被释放。
为了确保 GC 正在执行,我使用 jcmd 进行显式 GC:
- GC.run
- GC.run_finalization
- GC.run
然后,我制作了一个堆快照并使用 YourKit 分析器进行了分析(与 jvisualvm 的结果相同)。
我注意到在 3 天不活动后,我仍然有 2.5Gb 的“无法访问”对象。典型对象的传入引用如下所示(我有大约 700K 个此类对象):
我检查了 Apache HttpComponents 代码(HttpCore 版本 4.3.2),我注意到 EntityUtils.toString(我在我的服务器中使用)中有以下奇怪的代码:
在我看来,由于 reader 对象未关闭 - 它可以创建引用,最终导致我观察到的泄漏。
- 这是 Apache HttpCore EntityUtils 的泄漏代码吗?
- 还有其他原因导致 3 天后以及 GC 运行后出现这么多无法访问的对象吗?
谢谢。
最佳答案
考虑扩展AsyncCharConsumer
,如图所示here生成包含响应内容的字符串,或者如果需要更复杂的响应处理,则使用 HttpAsyncResponseConsumer 。
EntityUtil
方法通常适用于由阻塞 InputStream
支持的实体。即使这样,我通常也会建议直接从内容流中使用实体内容,而不是将其转换为字符串。
关于java - Apache HttpComponents EntityUtils 内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31707104/