如何发现 Java 中的内存泄漏(例如使用 JHat)?我尝试在 JHat 中加载堆转储来进行基本查看。但是,我不明白我应该如何找到根引用(ref)或无论它被称为什么。基本上,我可以看出有几百兆字节的哈希表条目([java.util.HashMap$Entry 或类似的东西),但是地图到处都在使用......有什么方法可以搜索大地图,或者也许找到大型对象树的一般根?
[编辑]
好吧,到目前为止我已经阅读了答案,但我们只能说我是一个小气的混蛋(这意味着我对学习如何使用 JHat 更感兴趣,而不是支付 JProfiler 的费用)。此外,JHat 始终可用,因为它是 JDK 的一部分。当然,除非 JHat 除了暴力之外别无他法,但我不敢相信会出现这种情况。
另外,我认为我无法实际修改(添加日志记录all地图大小)并运行足够长的时间让我注意到泄漏。
我使用以下方法来查找 Java 中的内存泄漏。我使用 jProfiler 取得了巨大成功,但我相信任何具有图形功能的专用工具(差异更容易以图形形式分析)都可以工作。
- 启动应用程序并等待其进入“稳定”状态,此时所有初始化均已完成并且应用程序处于空闲状态。
- 多次运行怀疑产生内存泄漏的操作,以允许进行任何缓存、与数据库相关的初始化。
- 运行 GC 并拍摄内存快照。
- 再次运行该操作。根据操作的复杂性和所处理的数据的大小,操作可能需要运行几次到多次。
- 运行 GC 并拍摄内存快照。
- 对 2 个快照运行差异并进行分析。
基本上,分析应该从最大的正差异开始,例如对象类型,并找出导致这些额外对象保留在内存中的原因。
对于在多个线程中处理请求的 Web 应用程序,分析变得更加复杂,但通用方法仍然适用。
我做了很多专门旨在减少应用程序内存占用的项目,这种通用方法加上一些特定于应用程序的调整和技巧总是效果很好。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)