如何使用Netbeans Profiler找到内存泄漏?

Yat*_*oel 15 java profiler netbeans

我想在我的java应用程序中找到内存泄漏,但我不知道如何使用Netbeans profiler来做到这一点.

Cli*_*ton 43

建立

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

首先,您需要对应用程序进行广泛搜索,以找出可能泄漏内存的一般区域/功能.因此,选择以下命令启动NetBeans探查器:

简介 - >简介项目(项目名称)

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

mem setup http://img268.imageshack.us/img268/1/mem01.png

广泛搜索

因此,当您泄漏内存并帮助指导搜索时,您可以看到遥测概览(在下图中标记为A).

在进行大范围搜索时,您希望继续运行一系列步骤,使您的应用程序在执行某些操作时返回到原始的"干净"状态.在我的例子中,我几乎将一些数据插入到我的应用程序中(文件 - >打开),显示它(显示)然后将其全部清除(文件 - >新).在我完成文件 - > new后,我期待使用的堆和幸存的代数与我开始时相同...如果它们在垃圾收集器运行后仍然很高,那么你已经泄漏了一些内存.

alt text http://img188.imageshack.us/img188/3401/mem02.png

缩小搜索范围

现在您已经在应用程序中发现了泄漏内存的功能,现在是时候缩小搜索范围并确切地确定哪些对象仍然被引用.这是通过"堆转储"在NetBeans探查器中完成的:

简介 - >采取堆转储......

这将在摘要页面上显示堆,切换到类视图并通过输入根软件包名称来筛选项目类,即:org.yourproject,按实例[%]排序,您将拥有正在使用的对象大多数记忆:

alt text http://img69.imageshack.us/img69/8200/mem03.png

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

简介 - >采取堆转储......

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

左下角是您双击的特定类的所有实例,如果您选择一个,其字段和引用将填充在右侧.由于我们怀疑这个对象可能正在泄漏,因此必须要有一些参考.右键单击引用列表中的"this",然后选择"Show Nearest GC Root".如果对话框返回"未找到GC根",则表示Java虚拟机将在下一轮垃圾收集它,并且对象不负责泄漏内存.然而,如果树扩大,那么这可能是漏洞的罪魁祸首之一.

alt text http://img695.imageshack.us/img695/5080/mem04.png

这一步的关键是从列表顶部开始工作.在上图中,IntDataValue是我们认为正在泄漏的对象,树中的下一个东西是引用它的对象.Field是保存引用的变量,type是保存引用的对象的类型.当你按下列表的方式工作时,请继续点击源代码,并问自己以下内容:

为什么这个参考?

它应该持有参考吗?

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


更新:协助缩小搜索范围

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

替代文字

现在,运行您在广泛搜索期间发现泄漏的往返步骤并拍摄另一张快照.使用"另存为..."按钮将它们保存在可以找到它们的位置.

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

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

替代文字

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

替代文字

  • 这不应该是公认的答案吗? (2认同)

Mar*_*gón 3

网络上有多种资源可以为您提供帮助

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

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

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