以特定方法监视Java对象分配/释放

时间:2016-11-14 13:56:11

标签: java memory memory-management jvm java-memory-model

我想知道是否有任何轻量级方法(粗略地)测量给定Java类使用的内存量。让我们考虑以下界面:

interface MyAction <T, R> {
    R execute(T item);
}

我想知道在覆盖的execute方法中使用的所有对象实例化为字段或变量的内存量。当然,它还应该考虑在调用其他方法时创建的每个对象。 据我所知(阅读reply),最好的选择是:

  • 通过ASM框架修补JVM字节码,并在以下任何指令之前放置钩子:new,newarray,anewarray,multianewarray。

  • 通过更改JNI功能表来拦截所有JNI调用(如果有)。

  • 拦截所有VMObjectAlloc事件。

这三个步骤将涵盖所有可能的分配,但我无法弄清楚是否有任何好的方法来跟踪对象的释放。

我会修改finalize方法字节码,以便获得有关对象gc释放的通知并拦截所有ObjectFree事件(仅用于标记对象)。我很确定这不会涵盖所有的释放事件,因此我想知道是否有一些已知的技术(我无法找到)可以帮助我解决这个问题。

提前谢谢。

1 个答案:

答案 0 :(得分:0)

由于您对分配的内存量感兴趣,而不是每个分配的对象,您可以使用更简单的方法。

有一个方法ThreadMXBean.getThreadAllocatedBytes,它返回给定线程分配的累积内存量。您只需在调用com.sun.management.ThreadMXBean之前和之后记录计数器。差异将是方法分配的估计总内存(考虑到它不跨越多个线程)。

以下是获取 com.sun.management.ThreadMXBean mxBean = (com.sun.management.ThreadMXBean) ManagementFactory.getThreadMXBean(); 的实例的方法:

V2

Java中没有像对象释放这样的事件。在完整GC之前,您无法找到对象是否可访问。即便GC也没有“解除分配”#34;对象 - 它通常只是遍历活动对象,并将其他所有内容视为自由空间。

如果您需要在调用方法后查找Java堆如何更改,则可以在调用之前和之后创建堆快照。