java堆和线程分析的内存泄漏 [英] java heap and thread analysis for memory leak

查看:248
本文介绍了java堆和线程分析的内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



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



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



我已经回顾了线程转储,没有等待锁定对象的线程,线程类似于下面所示的线程,并没有明显的原因。根据你的堆转储,你最大的内存问题是 int数组,事实上它占用了堆的70% (是的,而不是排序大小列)。


  1. 在您的堆转储中选择它,右键单击并选择在实例视图中显示
  2. 然后浏览最大的对象,然后右键单击并选择 Show Nearest GC Root 来查看哪个对象仍然存在对int数组的严格引用,防止符合GC的条件。

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



请参阅下面的 Nearest GC Root 示例,以便识别我为了展示这个想法而故意添加到我的程序中的泄漏。正如你在屏幕截图中看到的那样,我有一个int数组,因为它存储在 HashMap 称为 leak 在我的类 Application 中,所以我知道我的内存问题可能是由于这个特定的 HashMap 特别是如果我有许多其他的对象导致这个 HashMap





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



另一个窍门是,如果您有



另一种方法是使用


My WebLogic server was configured with 16gb of heap space, but it was 90% used within 1 hour of production usage when most of the users started work. I observed there were several stuck threads whenever this happens.

I have captured the heap dump when the heap was approx 10% free. How do I inspect the heap dump to find out the memory leak, or process, codes which is causing this issue.

I have tried to understand the memory leak, running tools like JMap and Eclipse MAT, but it maybe due to lack of experience, I couldn't understand what these tools are trying to show. Or how/what should I look out for?

I have both the before/after GC heap dump to analyze.

I have reviewed the thread dumps, there were no "waiting to lock" objects threads, the threads were similar as shown below, with threads stuck with no obvious reasons.

解决方案

According to your heap dump, your biggest memory issue is the int arrays, indeed it takes nearly 70 % of your heap (Yes sort the Size Column instead).

  1. Select it in your heap dump, right click and select on Show in Instances View
  2. Then browse the biggest objects and for each of them right click and select Show Nearest GC Root to see which Object has still an hard reference to the int array which prevents to be eligible for the GC.

It could help you to find your memory leak assuming that it is a memory leak.

See below an example of Nearest GC Root allowing to identify a leak that I added intentionally to my program just to show the idea. As you can see in the screenshot, I have an array of int which cannot be eligible for the GC because it is stored in an HashMap called leak in my class Application, so I know that my memory issue could be due to this particular HashMap especially if I have many other objects which lead to this HashMap.

NB: Be patient when you try to identify a leak as it is not always obvious, the ideal situation is where you have a huge object that takes the whole heap but obviously it is not your case there is nothing really obvious that is the reason why I propose to investigate the int arrays first. Don't forget that it could also be little int arrays but thousands of them with the same Nearest GC Root.

Another trick, If you have JProfiler you can simply follow this wonderful tutorial to find your leak.

Response Update:

One simple way to better identify the root cause of the memory leak is to take at least 2 heap dumps then compare them using a tool like jhat with the syntax

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

It will launch a small HTTP sever on port 7000 so:

  1. Launch http://localhost:7000/
  2. Then click on Show instance counts for all classes (including platform)

You will then see the list of Classes ordered by total amount of new instances created. You can then use VisualVM to do what I described in the first part of my answer to find the root cause of your memory leak.

You can also use jhat

  1. By selecting of the Top Classes then for each of them
  2. click on one "Reference to this Object"
  3. then click on Exclude weak refs

You will then see the GC root of each instances like the next screenshot:

Another way is to use Eclipse Memory Analyzer also called MAT.

  1. Open the second snapshot with it
  2. Select the view histogram
  3. Then for each of the Top Classes right click
  4. Choose Merge Shortest Paths To GC Roots/ Exclude All references

you will then see something like the next screenshot:

这篇关于java堆和线程分析的内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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