我工作的公司负责构建Java“企业软件”:大型,复杂且通常设计和维护得不好的软件。我们经常遇到内存泄漏问题,这些问题会在数小时甚至数分钟之内显现出来。通过正常监视内存使用情况并在堆内存变得很严重时进行堆转储,可以清楚地看到这些内存泄漏。

根据我们的监控,它似乎在很长一段时间(数周甚至数月)内缓慢泄漏内存。单个内存转储无法提供有关内存泄漏位置以及随着时间的流逝如何发展的大量见解。

因此,我正在寻找一种可以定期生成/提供当前驻留在堆中每个类的数字实例报告的工具。很像jmap -histo可以提供。但是,由于它应该在生产实例上定期运行,因此开销应该很低,并且不会冻结JVM。

具有29K个实例的29M实例的活动堆的2GiB并不罕见。

最佳答案

从heapSpank.org签出heapSpank-我是作者。
heapSpank以您可以配置的间隔执行jmap -histo。
它显示了最有可能泄漏的15个类的字节数增加的时间百分比。
该百分比称为“泄漏百分比”-表示为LKY%。
LKY%为100%的类是最有可能泄漏的对象。

这是该方法的优点:


捕获jmap -histo数据的开销明显低于堆转储的开销。
无需重新启动JVM,就像连接分析器一样。
如果您愿意在生产中执行几次jmap -histo,那么heapSpank只会在此基础上增加少量开销。
开源和纯Java解决方案。
只需下载小的(2mb)可执行jar文件,然后传入泄漏的JVM的pid。


缺点:


不支持permgen / metaspace泄漏。
不支持jmap与远程JVM的连接。
仅适用于HotSpot JDK,不适用于IBM J9。
This link是我寻求支持J9的帮助请求。


这里有一些有关保持较低开销的说明。

This link提供有关配置的详细信息。
增加此间隔以进一步降低开销:

org.heapspank.jmap.histo.interval.seconds=5


默认情况下,为了保持较低的开销,heapSpank不会将-live参数传递给jmap -histo。
但是需要权衡。不使用-live参数将导致准确性较低的结果。

#If true, jmap -histo is passed the '-live' parameter,
#which forces a full GC with every jmap -histo run.
#Using true will identify leak suspects more quickly & accurately,
#but will incur extra GC overhead.
org.heapspank.jmap.histo.live=false


当前,heapSpank是带有unix'top'的display命令行程序。 The heapSpank roadmap表明我们希望将这种技术与常见/流行的开源监视工具和容器一起部署。

关于java - 监视堆上类的实例数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35433713/

10-09 05:14