gpt4 book ai didi

内存泄漏的java堆和线程分析

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:53:48 26 4
gpt4 key购买 nike

我的 WebLogic 服务器配置了 16gb 的堆空间,但当大多数用户开始工作时,它在生产使用的 1 小时内使用了 90%。我观察到每当发生这种情况时都会有几个线程卡住。

当堆空闲大约 10% 时,我捕获了堆转储。如何检查堆转储以找出导致此问题的内存泄漏或进程代码。

我试图通过运行 JMap 和 Eclipse MAT 等工具来了解内存泄漏,但可能由于缺乏经验,我无法理解这些工具试图显示的内容。或者我应该如何/注意什么?

我要分析之前/之后的 GC 堆转储。

我查看了线程转储,没有“等待锁定”对象线程,线程类似于下图,线程卡住,原因不明。

最佳答案

根据您的堆转储,您最大的内存问题是 int 数组,实际上它占用了将近 70% 的堆(是的,改为对 Size 列进行排序)。

  1. 在堆转储中选择它,右键单击并选择在实例 View 中显示
  2. 然后浏览最大的对象并为每个对象右键单击并选择 Show Nearest GC Root 以查看哪个对象仍然具有对 int 数组的硬引用,这阻止了 GC 的资格。

假设它是内存泄漏,它可以帮助您找到内存泄漏。

请参阅下面的 Nearest GC Root 示例,它可以识别我故意添加到我的程序中的泄漏,只是为了展示这个想法。正如您在屏幕截图中看到的,我有一个 int 数组,它不符合 GC 的条件,因为它存储在我的类 中名为 leakHashMap 中Application,所以我知道我的内存问题可能是由于这个特定的 HashMap 造成的,尤其是当我有许多其他对象导致这个 HashMap 时。

enter image description here

注意:当您尝试识别泄漏时请耐心等待,因为它并不总是很明显,理想情况是您有一个巨大的对象占用整个堆,但显然这不是您的情况没有什么是真正明显的,这就是我建议首先研究 int 数组的原因。不要忘记它也可以是小整数数组,但其中有数千个具有相同的 Nearest GC Root

另一个技巧,如果你有JProfiler你可以简单地关注this wonderful tutorial找到你的漏洞。

响应更新:

更好地识别内存泄漏根本原因的一种简单方法是至少进行 2 次堆转储,然后使用 jhat 等工具对它们进行比较。使用语法

jhat -J-Xmx2G -baseline ${path-to-the-first-heap-dump} ${path-to-the-second-heap-dump}

它将在端口 7000 上启动一个小型 HTTP 服务器,因此:

  1. 启动 http://localhost:7000/
  2. 然后点击Show instance counts for all classes (including platform)

然后您将看到按创建的新实例总数排序的类列表。然后,您可以使用 VisualVM 执行我在回答的第一部分中描述的操作,以找到内存泄漏的根本原因。

你也可以使用jhat

  1. 通过选择顶级类(class),然后为每个类(class)选择
  2. 点击一个“对此对象的引用”
  3. 然后点击Exclude weak refs

然后您将看到每个实例的 GC 根,如下图所示:

enter image description here

另一种方法是使用 Eclipse Memory Analyzer也称为 MAT

  1. 用它打开第二个快照
  2. 选择 View 直方图
  3. 然后为每个 Top Classes 右击
  4. 选择 Merge Shortest Paths To GC Roots/Exclude All references

然后您将看到类似下一个屏幕截图的内容:

enter image description here

关于内存泄漏的java堆和线程分析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37593549/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com