我试图找出应用程序的内存泄漏MAT
,在这里list_object
我找到了一些数值 intShallow heap
和retained heap
column。这些值是什么,以及如何知道内存泄漏在哪里。
3 回答
来自Nikita Salnikov-Tarnovski 的博客:
浅堆很简单——它只包含对象本身占用的堆。如何计算它有一些细微差别,但在本文的范围内,我们保持不变。请继续关注同一主题的未来帖子。
保留堆在许多方面更有趣。您很少对浅堆感兴趣,在大多数情况下,您的实际问题可以翻译为“如果我从内存中删除这个对象,垃圾收集器现在可以释放多少内存”。
现在,我们都记得,所有 Java 垃圾收集 (GC) 算法都遵循以下逻辑:
1)有些对象被 GC 认为是“重要的”。这些被称为 GC 根,并且(几乎)从未被丢弃。例如,它们是当前正在执行的方法的局部变量和输入参数、应用程序线程、来自本机代码的引用以及类似的“全局”对象。
2) 假定从这些 GC 根引用的任何对象都在使用中,因此不会被 GC 丢弃。在 Java 中,一个对象可以以不同的方式引用另一个对象,在最常见的情况下,对象 A 存储在对象 B 的字段中。在这种情况下,我们说“B 引用 A”。
3) 重复该过程,直到所有可以从 GC 根传递到达的对象都被访问并标记为“正在使用”。
4)其他所有东西都是未使用的,可以扔掉。
浅层与保留堆
浅堆是一个对象消耗的内存。一个对象每个引用需要 32 位或 64 位(取决于操作系统架构),每个整数 4 个字节,每个 Long 8 个字节等。根据堆转储格式,可以调整大小(例如对齐到 8,等等... ) 以更好地模拟 VM 的实际消耗。
X 的保留集是当 X 被垃圾回收时将被 GC 删除的对象集。
X 的保留堆是 X 的保留集中所有对象的浅层大小的总和,即由 X 保持活动的内存。
一般来说,对象的浅堆是它在堆中的大小,同一对象的保留大小是当对象被垃圾回收时将释放的堆内存量。
前导对象集的保留集,例如特定类的所有对象或由特定类加载器加载的所有类的所有对象,或者只是一堆任意对象,是如果所有对象都被释放的对象集该领先集变得无法访问。保留集包括这些对象以及只能通过这些对象访问的所有其他对象。保留大小是保留集中包含的所有对象的总堆大小。
最小保留大小给出了对保留大小的良好(低估)估计,其计算方式比一组对象的确切保留大小更快。它只取决于检查集中的对象数量,而不是堆转储中的对象数量。
简单来说,对象的浅堆是它在堆中的大小,同一对象的保留大小是当对象被垃圾回收时将释放的堆内存量。 更多细节