有一段时间我一直在摆弄 Java 堆。使用JVMTI
,我们可以跟踪java堆。
但是有什么方法可以使用纯java实现相同的目的吗?
我正在使用 java 工具和 asm 框架在运行时进行类转换。
我的目标是跟踪创建的每个对象,这意味着我需要定期检查它们的大小。我可以检查是否使用 asm 创建了新对象。我需要的是检查从堆空间创建的对象的大小。
这方面有什么指示吗?
编辑于 2013 年 12 月 28 日
好吧,我能够从 ASM 做一些事情,尽管它可能不是最好的解决方案(最好的方法是 JVMTI
我完全同意)。
我必须重写 visitVarInsn
(对于局部变量)、 visitFieldInsn
(对于实例和类变量)和 visitTypeInsn
(对于 NEW
和 NEWARRAY
对象正在创建)
每次创建一个新对象时,我都会记录该对象(是的,我知道这不是一个好方法,这可能会导致资源泄漏。如果您有更好的解决方案,请告诉我。我需要太糟糕了 [:( ] ) 我会定期检查对象大小。
您能给我提供更好的选择吗? (正如 Stephen 正确指出的那样,这种对象记录肯定行不通,但我对 JVMTI 都不满意 [:(])。另外,请原谅我的无知,我找不到合适的MXBean
方法。
MemoryMXBean有 getHeapMemoryUsage()
,但我无法通过此方法跟踪单个对象的大小。也许我应该编写自己的 MBean
。
最佳答案
我想理论上你可以做到。对象的(浅)大小很容易根据对象字段的数量和类型来计算,并且您可以使用 ASM 工具将代码插入到每个构造函数中,以在每次构造对象时记录大小(某处)。
处理数组会很棘手。数组分配不需要构造函数,因此您需要检测创建数组的所有位置。由于其中一些地方可能位于 native 代码中,因此很难看出您将如何执行此操作。
另一个棘手的情况是处理创建对象而不调用其构造函数的事物;例如对象序列化和 native 克隆。
总而言之,这可能不是一个实用的方法。
另一点是,任何使用 ASM 和类似内容的东西可以说都不是“纯 Java”......除非该用法实际上是 JVM 本身的一部分。
关于java - 不使用 native 代码跟踪 java 堆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20795767/