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