2

我正在旧 Java 应用程序中使用 MAT(Analyzing Heap Dump)调试 OutOfMemory 问题。MAT 显示 RMI 线程创建了 My Business Object(BO) 的 Array(BO[150K+]),它有 150k+ 个实例,它消耗大约 358 MB(Xmx 是 512 MB)。这是一种内存泄漏情况。

在所有转储(在服务器崩溃后创建)中,我注意到一个更有趣的部分,Array Object 中的实例数量是相同的。

我无法理解如何找出这个 Array Object ,这个数组对象是在哪个类中创建的。MAT 中是否有任何此类直接/间接功能?

请建议在 visualVM 或其他工具中是否有任何此类选项。或者一些我可以在代码库上运行的内存分析器。

4

3 回答 3

1

在 Eclipse MAT histogram 中选择数组对象并右键单击并选择

"merge shortest path to GC Root" (exclude weak references) ,

这应该向您显示创建路径一直到创建此数组的基类对象。

在此处输入图像描述

于 2014-09-19T20:38:52.943 回答
0

有在 vanilla jVisualVM 中的堆转储上使用 OQL 的功能。OQL 中的功能之一是 heap.livepaths,它以实例为参数,输出所有阻止垃圾回收的路径。
如果您有一个您知道不应该存在的具体类或对象(相关窗口因摇摆而关闭并且垃圾收集器被强制多次),您可以列出这些路径并获取几个参考路径示例。
冲洗并重复,直到所有可疑对象都被垃圾收集。然后它变得更加困难,因为您不再有潜在客户,但您可能在您的应用程序中发现了几个错误,并且可能已将其修复到可接受的程度。

注意:我通常会非常努力地分析内存泄漏,它可能不适用于非常复杂的应用程序。

于 2014-05-15T20:09:22.963 回答
0

如果您需要一个可以向您显示分配实例的位置的分析器,您可以尝试JProfiler。堆遍历器有一个“分配”视图,您可以在其中查看任何对象集的累积调用堆栈。要获得分配调用堆栈,您必须打开分配记录,可能在启动时。

在此处输入图像描述

免责声明:我公司开发JProfiler

于 2014-05-15T20:01:47.710 回答