如何使用 Netbeans 分析器查找内存泄漏?

发布于 2024-08-07 21:33:33 字数 1566 浏览 1 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

〃温暖了心ぐ 2024-08-14 21:33:33

设置

由于此处的一些链接有点过时并且针对 NetBeans 6.0,因此以下是使用 Netbeans 6.8

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

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

然后按如下方式设置你的分析器:

mem setup

宽搜索

这样您就可以看到内存泄漏的情况,并帮助指导您的搜索,调出遥测概述(在下图中标记为 A)。

在进行广泛的搜索时,您希望继续运行一系列步骤,使您的应用程序从执行某些操作返回到原始的“干净”状态。就我而言,我几乎将一些数据插入到我的应用程序中(文件 - >打开),显示它(显示),然后清除所有数据(文件 - >新)。在我完成 file->new 后,我期望已用堆和幸存代数与我开始时相同...如果垃圾收集器运行后它们仍然很高,则说明您泄漏了一些内存。

替代文本

缩小搜索范围

既然您已经在应用程序中发现了内存泄漏的功能,那么是时候缩小搜索范围并准确找出仍在引用哪些对象了。这是通过在 NetBeans 分析器中进行“堆转储”来完成的:

简介->进行堆转储...

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

alt text

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

简介->进行堆转储...

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

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

替代文本

这一步的关键是从列表顶部向下进行。在上图中,IntDataValue 是我们认为正在泄漏的对象,树中的下一个对象是引用它的对象。 Field 是保存引用的变量,type 是保存它的对象的类型。当你沿着列表往下看时,不断地翻到源代码并问自己以下问题:

为什么要保留引用?

它应该保留参考吗?

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


更新:协助缩小搜索范围

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

alt text

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

选择个人资料 ->比较内存快照...

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

alt text

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

alt text

Setup

Since some of the links here are a little out of date and targeted at NetBeans 6.0, the following is a little update for plugging memory leaks in Java desktop applications using Netbeans 6.8.

To begin, you need to perform a wide search of your application to find what general areas/features that might be leaking memory. So start up the NetBeans profiler by selecting:

Profile -> Profile Project(project
name)

Then setup your profiler as follows:

mem setup

Wide Search

So you can see when you leak memory and to help guide your search, bring up the telemetry overview (Marked as A in the picture below).

When doing wide searches, you want to keep running a bunch of steps that takes your application on a round trip from doing something, back to the originating "clean" state. In my case, I pretty much inserted some data into my application (file->open), displayed it (show) and then cleared it all (file->new). After I had done file->new I was expecting the used heap and number of surviving generations to be the same as when I started... If they are still high after the garbage collector has run, you have leaked a bit of memory.

alt text

Narrowing the Search

Now that you have found a feature in your application that leaks memory, it is time to narrow the search and figure out exactly what objects are still being referenced. This is done in the NetBeans profiler by taking "heap dumps":

Profile -> Take Heap Dump...

This will bring up the heap on a summary page, switch to the classes view and filter for your projects classes by entering the root package name i.e: org.yourproject, sort by Instances [%] and you will have the objects that are consuming the most memory:

alt text

Now, run the round trip steps you found to be leaking during the wide search and take another heap dump:

Profile -> Take Heap Dump...

By comparing the two lists, look for classes that have more instances in the second dump than in the first. Classes with more instances could be the ones leaking memory. In the second dump file, double click the class that could be the one leaking to bring it up in the instances view:

Down the left are all the instances of the particular class you double clicked on and if you select one, its fields and references will be populated in the right. Since we suspect this object might be leaking, something must still be holding a reference to it. Right click on "this" in the reference list and select "Show Nearest GC Root". If a dialog comes back with "No GC root found", that means the Java Virtual Machine will garbage collect it next time round and the object is not responsible for the leaking memory. If however, the tree expands then this could be one of the leaky culprits.

alt text

The key to this step, is to work from the top of the list down. In the image above, IntDataValue is the object we think is leaking, and the next thing down in the tree is the object that is referencing it. Field is the variable that is holding the reference, and type is the type of object that is holding it. When working your way down the list keep flicking to the source code and ask yourself the following:

Why is this holding a reference?

Should it be holding a reference?

While walking down the tree, asking myself these questions I often find that running the debugger and stepping through code, is the only way to find the answers.


UPDATE: Assisting with narrowing the search

Above is the original mechanisim I was using to narrow the search, but I have found another way to help narrow the search by using the "Compre memory snapshot..." feature in the "Profile" menu. First take a snapshot (see screenshot).

alt text

Now, run the round trip steps you found to be leaking during the wide search and take another snapshot. Save them somewhere you can find them using the Save As... button.

Select Profile -> Compare Memory Snapshot...

Select the two snapshots, being careful to put the first snapshot in the top slot, and the second snapshot in the bottom slot (otherwise you will get incorrect negative memory changes):

alt text

This will generate a screen similar to the following, where the number of bytes is size of change in allocations between the two snapshots (i.e. large growths might be suspect memory leaks, along with the change in the number of allocations):

alt text

围归者 2024-08-14 21:33:33

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

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

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

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

There are several resources on the web that can give you a hand

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

In a nutshell, you monitor the "surviving generators", objects that are kept in the memory by your application.

When you see that this metric gets out of hand, you can switch to the Memory Live profiling mode, sort the classes by surviving generators and then with the right click mouse button select the "Show Allocation Stack Traces" option

北城孤痞 2024-08-14 21:33:33

NetBeans 分析器的所有文档都可以在 NetBeans 网站上找到。他们有一个整个部分专门介绍分析器 - 从简介到高级使用!

All of the documentation for the NetBeans profiler can be found on the NetBeans website. They have an entire section devoted to the profiler - from an introduction to advanced use!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文