用于Java桌面应用程序的内存分析 [英] Memory profiling for Java desktop application

查看:89
本文介绍了用于Java桌面应用程序的内存分析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序加载了一个约数据集。 85bm到100mb每次。应用程序的内存限制设置为512mb,理论上这足够了。



然而,我发现如果在应用程序的单次运行中,我打开和关闭数据集5次,总内存消耗稳步增加,直到出现内存不足错误:

  PID用户PR NI VIRT RES SHR S%CPU%MEM TIME +命令
6882 bguiz 20 0 679m 206m 19m S 30 13.7 0:30.22 java
6882 bguiz 20 0 679m 259m 19m S 9 17.2 0:55.53 java
6882 bguiz 20 0 679m 301m 19m S 9 20.0 1:20.04 java
6882 bguiz 20 0 679m 357m 19m S 33 23.7 1:44.74 java
6882 bguiz 20 0 679m 395m 19m S 80 26.2 2:10.31 java

内存从大约14%增长到大约26%。它看起来像一个内存泄漏。



发生的事情是,正在加载的顶级数据用于填充地图和列表等集合,然后更详细数据用于创建这些顶级对象的子对象,然后它们又创建子子对象。



当数据集关闭时,当前应用程序确实试图通过取消填充各种对象集合来清除它的轨迹,然后显式调用 System.gc();






无论如何,这是应用程序的状态,当我接触它时(在我之前的几年中),我已经分配了这个任务。

我需要做的是找到一种方法来找到在数据集被卸载后哪些子对象和子子对象仍然相互引用,并修正它们。

显然这可以手动完成,但会非常繁琐,但是我觉得通过内存分析来做到这一点会更好,这是我之前没做过的事情。



我已经阅读了一些关于使用哪些内存分析工具的其他SO问题,并且我选择使用Netbeans IDE中内置的工具,因为它似乎有很好的评论,而且我在Netbeans工作。



有没有人在事前和事后做过类似的Java内存分析任务:




  • 你会给我什么具体建议?

  • 在解决这个问题时,您发现哪些技术有用?

  • 您发现哪些资源对解决此问题有用?






编辑:
此应用程序是标准的桌面应用程序 - 不是web应用程序。




编辑:已实施解决方案



基本上我的工作是将Netbeans的profiler与JHAT结合使用。



我发现内置于Netbeans IDE中的Profiler做得非常好在特定的分析点中创建内存转储,然后该工具能够按类过滤和排序,并深入查看每个实例的引用。这一切都非常好。



然而,它并没有提供我比较两个堆转储的方法。我问了一个后续问题,它看起来像JHAT(作为一部分



ThorbjørnRavn Andersen,Dmitry和Jason Gritman:您的意见非常有帮助,不幸的是我只能将1标记为正确的答案,而且你们所有人都从我那里得到了+1。

解决方案

我写了一个关于要去技术的另一个问题的答案关于如何在查找内存泄漏https://stackoverflow.com/questions/1716597/java -memory-leak-detection-tools / 1717260#1717260



如果您遵循我的建议,那么可以使用像 JProfiler 可以让您漫步物体的参考图并查看深层这些对象的大小。这可以帮助您找到任何仍然保留在数据上的对象或对象。



我没有和Netbeans合作过,所以我不能告诉你它是如何与我用过的其他配置文件堆叠起来的。如果看起来没有这个功能,您可以轻松获得JProfiler的试用版本,这应该会持续到您发现泄漏为止。


My application loads a data set of approx. 85bm to 100mb each time. The application's memory limit is set to 512mb, and this is, theoretically, more than enough.

However, I found that if, in a single run of the application, I opened and closed the data set 5 times, the total memory consumption steadily increases, until I get an out-of-memory error:

 PID USER  PR NI VIRT RES SHR S %CPU %MEM TIME+   COMMAND
6882 bguiz 20 0 679m 206m 19m S 30   13.7 0:30.22 java
6882 bguiz 20 0 679m 259m 19m S 9    17.2 0:55.53 java
6882 bguiz 20 0 679m 301m 19m S 9    20.0 1:20.04 java
6882 bguiz 20 0 679m 357m 19m S 33   23.7 1:44.74 java
6882 bguiz 20 0 679m 395m 19m S 80   26.2 2:10.31 java

Memory grew from ~14% to ~26%. It looks like a memory leak.

What's happening is that the top level data that is being loaded is used to populate collections such as maps and lists, and then the more detailed data is used to create sub-objects of these top-level objects, and then they in turn create sub-sub-objects.

When the data set is closed, currently the application does indeed make an attempt to clear its tracks by de-populating the various collections of objects, and then explicitly calling System.gc();


Anyhow, this is the state of the application when I got to it (several years in the making before me), and I have been assigned this task.

What I need to do, is to find a way to find which sub-objects and sub-sub-objects are still referencing each other after the data set is unloaded, and rectify them.
Obviously this can be done manually, but would be very very tedious, but I felt it would be a much better option to do this by memory profiling, something which I haven't done before.

I have read some other SO questions that asked about which memory profiling tools to use, and I have chosen to go with the one built into Netbeans IDE, since it seemed to have good reviews, and I am working in Netbeans anyway.

Has anyone undertaken a similar Java memory profiling task before, and with hindsight:

  • What specific advice would you give me?
  • What techniques did you find useful in tackling this problem?
  • What resources did you find useful in tackling this problem?

Edit: This application is a standard desktop application - not a web application.


Edit: Implemented solution

Basically what worked for me was to use Netbeans' profiler in conjunction with JHAT.

I found that the Profiler built into Netbeans IDE did a really good job of creating the memory dumps at particular profiling points, and then the tool was able to filter and sort by class and drill down the references for each instance. Which was all really good.

However, it didn't provide me with a means to compare two heap dumps. I asked a follow up question, and it looks like JHAT (comes as part of JDK) gets that job done quite well.

Thorbjørn Ravn Andersen, Dmitry and Jason Gritman: your input was really helpful, unfortunately I can only mark 1 as the correct answer, and all of you got +1 from me anyway.

解决方案

I wrote up an answer to another question about the techniques to go about finding memory leaks at https://stackoverflow.com/questions/1716597/java-memory-leak-detection-tools/1717260#1717260

If you follow my advice there, a tool like JProfiler can allow you to walk the reference graph of objects and view the deep size of those objects. This can help you find whatever object or objects are still holding onto the data.

I haven't worked with Netbeans, so I can't tell you how it stacks up against the other profilers I've used. If it doesn't look like it has that feature you can obtain a trial version of JProfiler easily, which should last you until you've found your leak.

这篇关于用于Java桌面应用程序的内存分析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆