java - 不使用 native 代码跟踪 java 堆

标签 java assembly bytecode

有一段时间我一直在摆弄 Java 堆。使用JVMTI,我们可以跟踪java堆。

但是有什么方法可以使用纯java实现相同的目的吗?

我正在使用 java 工具和 asm 框架在运行时进行类转换。

我的目标是跟踪创建的每个对象,这意味着我需要定期检查它们的大小。我可以检查是否使用 asm 创建了新对象。我需要的是检查从堆空间创建的对象的大小。

这方面有什么指示吗?

编辑于 2013 年 12 月 28 日

好吧,我能够从 ASM 做一些事情,尽管它可能不是最好的解决方案(最好的方法是 JVMTI 我完全同意)。

我必须重写 visitVarInsn (对于局部变量)、 visitFieldInsn (对于实例和类变量)和 visitTypeInsn (对于 NEWNEWARRAY 对象正在创建)

每次创建一个新对象时,我都会记录该对象(是的,我知道这不是一个好方法,这可能会导致资源泄漏。如果您有更好的解决方案,请告诉我。我需要太糟糕了 [:( ] ) 我会定期检查对象大小。

您能给我提供更好的选择吗? (正如 Stephen 正确指出的那样,这种对象记录肯定行不通,但我对 JVMTI 都不满意 [:(])。另外,请原谅我的无知,我找不到合适的MXBean 方法。

MemoryMXBeangetHeapMemoryUsage() ,但我无法通过此方法跟踪单个对象的大小。也许我应该编写自己的 MBean

最佳答案

我想理论上你可以做到。对象的(浅)大小很容易根据对象字段的数量和类型来计算,并且您可以使用 ASM 工具将代码插入到每个构造函数中,以在每次构造对象时记录大小(某处)。

处理数组会很棘手。数组分配不需要构造函数,因此您需要检测创建数组的所有位置。由于其中一些地方可能位于 native 代码中,因此很难看出您将如何执行此操作。

另一个棘手的情况是处理创建对象而不调用其构造函数的事物;例如对象序列化和 native 克隆。

总而言之,这可能不是一个实用的方法。


另一点是,任何使用 ASM 和类似内容的东西可以说都不是“纯 Java”......除非该用法实际上是 JVM 本身的一部分。

关于java - 不使用 native 代码跟踪 java 堆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20795767/

相关文章:

java - 在模态 JDialog 前面弹出一个 JFrame

java - 奇怪的 DexArchiveMergerException

c - 我们可以读取并错误注入(inject)另一个线程的程序计数器吗?

您可以在汇编中添加预处理器指令吗?

generics - Kotlin声明签名冲突?

java - 多线程弹跳球、显示球问题

java - 再次解析List<Map<String,String>> String形式为POJO

performance - 未对准的存储和未对准的负载哪一个更昂贵?

android - 在android上获取类字节码

java - 在类层次结构中混合 Java 1.4 和 1.6 字节码