1
55
如果不理解底层代码,几乎是不可能的。如果您了解底层代码,那么您可以更好地从堆转储中获取的海量信息中对小麦进行分类。 另外,你不知道什么东西是泄漏还是不泄漏,不知道为什么一开始就有这个类。 我刚刚花了几周的时间来做这个,我使用了一个迭代过程。 首先,我发现堆分析器基本上没用。他们无法有效地分析这些巨大的堆。 相反,我几乎完全依赖 jmap 柱状图。 我想你对这些很熟悉,但对那些不熟悉的人来说:
创建活动堆的柱状图。简而言之,它告诉您类名以及堆中每个类的实例数。 我每天24小时,每5分钟,定期倾倒垃圾。这对你来说可能太细了,但要点是一样的。 我对这些数据进行了几个不同的分析。 我编写了一个脚本来获取两个柱状图,并消除它们之间的差异。所以,如果JavaLang.Stand在第一个转储中是10,第二个是15,我的脚本会吐出“5 Java.Lang.Stand”,告诉我它上升了5。如果下降了,这个数字就会是负数。 然后,我将处理其中的几个差异,去掉从一个运行到另一个运行的所有类,并对结果进行联合。最后,我会列出在特定时间段内不断增长的类的列表。显然,这些都是泄漏类的主要候选者。 但是,一些类保留了一些类,而其他类是GC'D类。这些类可以很容易地整体上下移动,但仍然会泄漏。因此,他们可能会脱离“总是在上升”的阶级范畴。 为了找到这些,我将数据转换成一个时间序列,并将其加载到数据库postgres中。Postgres很方便,因为它提供 statistical aggregate functions ,所以你可以做简单的 linear regression analysis 在数据上,找到趋势向上的类,即使它们并不总是在图表上。我使用了regr_slope函数,查找具有正斜率的类。 我发现这个过程非常成功,而且非常有效。柱状图文件并不是非常大,很容易从主机下载。它们在生产系统上运行并不昂贵(它们强制使用大型GC,并且可能会暂时阻塞VM)。我是在一个2G Java堆的系统上运行的。 现在,所能做的就是识别潜在的泄漏类。 这就是理解如何使用这些类,以及它们是否应该是它们的参与方。 例如,您可能会发现您有很多map.entry类或其他一些系统类。 除非您只是在缓存字符串,否则事实是这些系统类,而“罪犯”可能不是“问题”。如果您正在缓存一些应用程序类,那么该类更能指示问题所在。如果不缓存com.app.yourbean,则不会将关联的map.entry绑定到它。 一旦拥有了一些类,就可以开始对代码库进行爬行,以查找实例和引用。由于您有自己的ORM层(无论是好是坏),所以至少可以很容易地查看它的源代码。如果您的ORM正在缓存东西,那么它很可能正在缓存包装应用程序类的ORM类。 最后,您可以做的另一件事是,一旦您了解了类,就可以用一个更小的堆和更小的数据集启动服务器的本地实例,并使用其中一个配置文件来反对它。 在这种情况下,您可以进行单元测试,只影响您认为可能泄漏的1个(或少数)东西。例如,您可以启动服务器,运行柱状图,执行单个操作,然后再次运行柱状图。你的漏课应该增加1(或者你的工作单元是什么)。 探查器可能会帮助您跟踪“现在泄漏”类的所有者。 但是,最后,您必须对代码库有一些了解,以便更好地理解什么是泄漏,什么不是泄漏,以及为什么对象存在于堆中,更不用说为什么它可能作为泄漏保留在堆中了。 |
2
13
看看 Eclipse Memory Analyzer . 它是一个很好的工具(并且是独立的,不需要安装Eclipse本身),它1)可以很快地打开非常大的堆,2)有一些非常好的自动检测工具。后者并不完美,但EMA提供了许多非常好的方法来浏览和查询转储中的对象,以发现任何可能的泄漏。 我过去用它来帮助查出可疑的泄漏。 |
3
5
这个答案扩展到了@will hartung's。我应用了相同的过程来诊断我的一个内存泄漏,并认为分享细节可以节省其他人的时间。 其想法是让Postgres“绘图”时间与每个类的内存使用率进行比较,绘制一条总结增长情况的线,并确定增长最快的对象:
将堆转储(需要多个)转换为一种格式这便于Postgres使用堆转储格式:
到具有每个堆转储日期时间的csv文件:
使用此脚本:
创建要放入数据的表
将数据复制到新表中
对大小(字节数)查询运行slop查询:
解释结果:
斜率是每秒添加的字节数(因为epoch的单位是秒)。如果使用实例而不是大小,那么这就是每秒添加的实例数。 创建这个joe.schmoe.businessobject的一行代码负责内存泄漏。它正在创建对象,将其附加到数组中,而不检查它是否已经存在。其他对象也与泄漏代码附近的BusinessObject一起创建。 |
4
3
你能加快时间吗?也就是说,你能写一个虚拟测试客户机,迫使它在几分钟或几小时内完成数周的呼叫/请求等吗?这些是你最大的朋友,如果你没有-写一个。 不久前,我们使用NetBeans分析堆转储。它可能有点慢,但很有效。Eclipse刚刚崩溃,32位Windows工具也崩溃了。 如果您可以访问64位系统或具有3GB或更高版本的Linux系统,您会发现分析堆转储更容易。 您是否可以访问更改日志和事件报告?大型企业通常会有变更管理和事件管理团队,这对于在问题开始发生时跟踪可能很有用。 什么时候开始出问题了?与人们交谈,尝试了解一些历史。你可能会有人说,“是的,是在他们修复了6.43补丁中的XYZ之后,我们发生了一些奇怪的事情。” |
5
2
我在IBM取得了成功 Heap Analyzer . 它提供了堆的几个视图,包括对象大小的最大下降量、最常见的对象以及按大小排序的对象。 |
6
1
如果它发生在使用一周之后,并且您的应用程序像您描述的那样是拜占庭式的,那么您最好每周重新启动它? 我知道这不是解决问题,但它可能是一个时间有效的解决方案。有没有时间窗口可以让你停机?在保持第二个实例的运行的同时,您能否实现负载平衡和故障转移?当内存消耗超过某个限制(可能通过JMX或类似工具进行监控)时,您可能会触发重新启动。 |
krtsz · 在标准Java之后启动JavaEE项目 7 年前 |
Fittoburst · iOS企业开发者计划规则 10 年前 |
dacology · Mule社区版与企业版-功能比较? 10 年前 |