如何使用 Netbeans 分析器查找内存泄漏?[已关闭]

2022-09-03 08:49:59

我想在我的 java 应用程序中查找内存泄漏,但我不知道如何使用 Netbeans profiler 来执行此操作。


答案 1

设置

由于此处的一些链接有点过时,并且针对 NetBeans 6.0,因此下面是一些更新,用于在使用 Netbeans 6.8 的 Java 桌面应用程序中插入内存泄漏。

首先,您需要对应用程序执行广泛的搜索,以查找可能泄漏内存的一般区域/功能。因此,通过选择以下选项启动 NetBeans 分析器:

型材->型材项目(项目名称)

然后按如下方式设置探查器:

mem setup

广泛搜索

因此,你可以查看何时泄漏内存,为了帮助指导搜索,请调出遥测概述(在下图中标记为 A)。

在执行广泛搜索时,您希望继续运行一堆步骤,这些步骤使您的应用程序从执行某些操作返回到原始的“干净”状态。在我的情况下,我几乎将一些数据插入到我的应用程序中(file->open),显示它(显示),然后全部清除(file->new)。在我完成文件>new之后,我期望使用的堆和幸存的世代数与我开始时相同......如果垃圾回收器运行后它们仍然很高,则表示您泄漏了一点内存。

alt text

缩小搜索范围

现在,您已经在应用程序中发现了一个泄漏内存的功能,现在是时候缩小搜索范围并确切地找出仍在引用的对象。这是在 NetBeans 探查器中通过获取“堆转储”来完成的:

配置文件 -> 采取堆转储...

这将在摘要页面上显示堆,切换到类视图并通过输入根包名称(即:org.yourproject)来筛选项目类,按实例[%]排序,您将拥有消耗最多内存的对象:

alt text

现在,运行您在广泛搜索期间发现泄漏的往返步骤,并执行另一个堆转储:

配置文件 -> 采取堆转储...

通过比较这两个列表,查找第二个转储中实例数多于第一个转储的类。具有更多实例的类可能是泄漏内存的类。在第二个转储文件中,双击可能是泄漏的类,以在实例视图中显示它:

左侧下方是您双击的特定类的所有实例,如果选择一个实例,则其字段和引用将填充在右侧。由于我们怀疑此对象可能正在泄漏,因此某些内容必须仍然包含对它的引用。右键单击参考列表中的“this”,然后选择“显示最近的GC根”。如果对话框返回“未找到GC根目录”,则表示Java虚拟机下次将对其进行垃圾回收,并且该对象不对泄漏的内存负责。然而,如果这棵树膨胀了,那么这可能是漏水的罪魁祸首之一。

alt text

此步骤的关键是从列表顶部向下工作。在上图中,IntDataValue 是我们认为泄漏的对象,树中的下一件事是引用它的对象。字段是保存引用的变量,类型是保存引用的对象的类型。在列表中工作时,请继续轻拂源代码,并问自己以下问题:

为什么这是一个参考?

它应该持有一个参考吗?

在树上行走时,经常问自己这些问题,我经常发现运行调试器并单步执行代码是找到答案的唯一方法。


更新:协助缩小搜索范围

以上是我用来缩小搜索范围的原始机制,但我找到了另一种方法来帮助缩小搜索范围,方法是使用“Compre内存快照...”功能在“配置文件”菜单中。首先拍摄快照(见截图)。

alt text

现在,运行在广泛搜索期间发现泄漏的往返步骤,并拍摄另一个快照。将它们保存在可以使用“另存为”找到它们的地方...按钮。

选择配置文件 ->比较内存快照...

选择两个快照,小心地将第一个快照放在顶部插槽中,将第二个快照放在底部插槽中(否则您将获得不正确的负内存更改):

alt text

这将生成一个类似于以下内容的屏幕,其中字节数是两个快照之间分配变化的大小(即,大量增长可能是可疑的内存泄漏,以及分配数的变化):

alt text


答案 2

网络上有几个资源可以为您提供帮助

http://www.javapassion.com/handsonlabs/nbprofilermemory/

http://www.netbeans.org/kb/articles/nb-profiler-uncoveringleaks_pt1.html

http://kirk.blog-city.com/more_on_memory_leaks.htm

简而言之,您可以监视“幸存的生成器”,即应用程序保存在内存中的对象。

当您看到此指标失控时,可以切换到 Memory Live 分析模式,按幸存的生成器对类进行排序,然后右键单击鼠标按钮选择“显示分配堆栈跟踪”选项


推荐