如何找到Java内存泄漏 [英] How to find a Java Memory Leak

查看:182
本文介绍了如何找到Java内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在Java中找到内存泄漏(例如,使用JHat)?我试图在JHat中加载堆转储以获得基本外观。但是,我不明白我应该如何找到根参考( ref )或其他任何东西。基本上,我可以说有几百兆字节的哈希表条目([java.util.HashMap $ Entry或类似的东西),但地图遍布整个地方...有没有办法搜索大地图,或者可能找到大型对象树的一般根源?

How do you find a memory leak in Java (using, for example, JHat)? I have tried to load the heap dump up in JHat to take a basic look. However, I do not understand how I am supposed to be able to find the root reference (ref) or whatever it is called. Basically, I can tell that there are several hundred megabytes of hash table entries ([java.util.HashMap$Entry or something like that), but maps are used all over the place... Is there some way to search for large maps, or perhaps find general roots of large object trees?


好​​的,到目前为止我已经阅读了答案,但我们只是说我是一个便宜的混蛋(意思是我更感兴趣的是学习如何使用JHat而不是支付JProfiler)。此外,JHat始终可用,因为它是JDK的一部分。除非当然没有办法与JHat合作但是蛮力,但我不敢相信可能是这样。

Ok, I've read the answers so far but let's just say I am a cheap bastard (meaning I am more interested in learning how to use JHat than to pay for JProfiler). Also, JHat is always available since it is part of the JDK. Unless of course there is no way with JHat but brute force, but I can't believe that can be the case.

另外,我认为我不会实际修改(添加所有地图大小的记录)并运行它足够长的时间让我注意到泄漏。

Also, I do not think I will be able to actually modify (adding logging of all map sizes) and run it for long enough for me to notice the leak.

推荐答案

我使用以下方法在Java中查找内存泄漏。我已经使用jProfiler取得了巨大的成功,但我相信任何具有图形功能的专业工具(差异更容易以图形形式分析)都可以。

I use following approach to finding memory leaks in Java. I've used jProfiler with great success, but I believe that any specialized tool with graphing capabilities (diffs are easier to analyze in graphical form) will work.


  1. 启动应用程序并等到达到稳定状态,此时所有初始化完成并且应用程序处于空闲状态。

  2. 运行怀疑产生内存泄漏的操作多次允许任何缓存,与DB相关的初始化。

  3. 运行GC并获取内存快照。

  4. 再次运行操作。根据操作的复杂性和处理的数据大小,操作可能需要运行几次到多次。

  5. 运行GC并获取内存快照。

  6. 为2个快照运行差异并进行分析。

  1. Start the application and wait until it get to "stable" state, when all the initialization is complete and the application is idle.
  2. Run the operation suspected of producing a memory leak several times to allow any cache, DB-related initialization to take place.
  3. Run GC and take memory snapshot.
  4. Run the operation again. Depending on the complexity of operation and sizes of data that is processed operation may need to be run several to many times.
  5. Run GC and take memory snapshot.
  6. Run a diff for 2 snapshots and analyze it.

基本上分析应该从最大的正差异开始,比如对象类型并找出导致这些额外对象留在内存中的原因。

Basically analysis should start from greatest positive diff by, say, object types and find what causes those extra objects to stick in memory.

对于在多个线程中处理请求的Web应用程序,分析变得更复杂,但仍然适用一般方法。

For web applications that process requests in several threads analysis gets more complicated, but nevertheless general approach still applies.

我做了很多项目,专门用于减少应用程序的内存占用,这种一般方法通过一些特定于应用程序的调整和技巧总是运行良好。

I did quite a number of projects specifically aimed at reducing memory footprint of the applications and this general approach with some application specific tweaks and trick always worked well.

这篇关于如何找到Java内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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