一尘不染

如何找到Java内存泄漏

java

您如何找到Java中的内存泄漏(例如使用JHat)?我试图在JHat中加载堆转储,以进行基本了解。但是,我不明白我应该如何找到根引用(ref)或任何被称为根引用的东西。基本上,我可以说哈希表条目有几百兆字节([java.util.HashMap $ Entry或类似的东西),但是地图到处都是……使用某种方法可以搜索大型地图,还是找到大对象树的一般根?

[编辑]好的,到目前为止,我已经阅读了答案,但是我们只能说我是个贱人(这意味着我对学习如何使用JHat而不是为JProfiler付费更感兴趣)。另外,由于JHat是JDK的一部分,因此始终可用。除非当然不能使用JHat,否则只能使用蛮力,但我不敢相信这种情况。

另外,我认为我将无法进行实际修改(添加所有地图尺寸的记录)并运行足够长的时间,以至于我无法注意到泄漏。


阅读 337

收藏
2020-03-01

共1个答案

一尘不染

我使用以下方法来查找Java中的内存泄漏。我使用jProfiler取得了巨大的成功,但是我相信任何具有图形功能的专业工具(差异更容易以图形形式进行分析)都可以使用。

  1. 当所有初始化完成且应用程序处于空闲状态时,启动应用程序并等待其进入“稳定”状态。
  2. 多次运行怀疑会导致内存泄漏的操作,以允许发生任何与数据库相关的高速缓存。
  3. 运行GC并获取内存快照。
  4. 再次运行该操作。根据操作的复杂性和已处理数据的大小,可能需要运行几次到很多次。
  5. 运行GC并获取内存快照。
  6. 对2个快照运行差异并进行分析。
    基本上,分析应该从最大的正差异开始,例如,对象类型,并找出导致这些额外对象滞留在内存中的原因。

对于在多个线程中处理请求的Web应用程序,分析变得更加复杂,但是仍然可以使用常规方法。

我做了很多专为减少应用程序的内存占用量的项目,并且这种通过一些特定于应用程序的调整和技巧的通用方法始终可以很好地工作。

2020-03-01