java - 监视特定方法中的 Java 对象分配/释放

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

我想知道是否有任何轻量级方法可以(粗略地)测量给定 Java 类使用了多少内存。让我们考虑以下接口(interface):

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

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

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

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

  • 拦截所有 VMObjectAlloc 事件。

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

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

提前谢谢您。

最佳答案

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

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

以下是获取com.sun.management.ThreadMXBean实例的方法:

    com.sun.management.ThreadMXBean mxBean =
            (com.sun.management.ThreadMXBean) ManagementFactory.getThreadMXBean();

Java中没有对象释放这样的事件。在 Full GC 之前,你无法确定对象是否可达。即使 GC 也不会“释放”对象 - 它通常只是遍历 Activity 对象,并将其他所有内容视为可用空间。

如果您需要了解调用方法后Java堆如何变化,您可以在调用之前和之后创建堆快照。

关于java - 监视特定方法中的 Java 对象分配/释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40590414/

相关文章:

c - 关于C中栈分配的问题

c++动态分配变量,执行流程是什么?

java - 如何在struts2中为自定义拦截器添加exportMethods参数列表

java - 如果 HashMap 中的两个键相同,如何打印错误消息? (JAVA)

java - 获取int中位数的方法?

php - WordPress 无法加载(连接超时)

c++ - 类成员内存分配

c - 重新分配与其偏移量不同的已分配内存块

linux - 如何在 ucontext* ,linux 中释放堆栈?

java - 运行Shell脚本作为Spark作业的一部分