目前,我正在开发一个Java代理来组装内存统计信息。在instrumentation API的帮助下,我可以控制类(并操纵它们)。使用普通Java,我可以估计每个对象使用的资源。到目前为止,一切都很好。
我现在面临的问题是“如何获取一个特定类的每个Object示例”。我可以通过字节码操作来获取对象示例,但我希望有另一个我不知道的API,帮助我完成我的目标,而不需要这样一个相当沉重的侵入步骤。最后,性能影响应该保持在最低限度。有什么想法吗?
目前,我正在开发一个Java代理来组装内存统计信息。在instrumentation API的帮助下,我可以控制类(并操纵它们)。使用普通Java,我可以估计每个对象使用的资源。到目前为止,一切都很好。
我现在面临的问题是“如何获取一个特定类的每个Object示例”。我可以通过字节码操作来获取对象示例,但我希望有另一个我不知道的API,帮助我完成我的目标,而不需要这样一个相当沉重的侵入步骤。最后,性能影响应该保持在最低限度。有什么想法吗?
6条答案
按热度按时间aurhwmvo1#
Eclipse中的调试器可以使用show you all the instances of a class,所以我查看了Eclipse的源代码。Eclipse使用Java Debug Wire Protocol,它允许您(从Java 6开始)查找所请求类的所有示例。如果您想沿着这条路走下去,请获取Eclipse源代码的副本,并检查
org.eclipse.jdi.internal.ReferenceTypeImpl
的instances
方法。一种更简单的方法是使用Java Debug Interface。请注意
ReferenceType.instances
方法。我还没有弄清楚如何使用JDI连接到一个正在运行的进程,以及如何获得
ReferenceType
的示例。JDK包含了几个examples,所以我确信这是可行的。9wbgstp72#
当我读到这篇文章的时候,我在想,既然java分析器已经存在了,那么一定有什么方法可以得到这样的信息。http://java.sun.com/j2se/1.4.2/docs/guide/jvmpi/jvmpi.html。它描述了JVM和性能分析器代理之间的接口。但是如果你真的想用Java来编写它,你可能就不走运了。
具体来说,看看这个函数:
8ehkhllq3#
正如在其他答案中所解释的,您可以通过使用JDI协议来实现它。它相当简单:您需要使用以下命令在调试模式下运行JVM
--agentlib:jdwp=传输=dt_套接字,服务器=y,挂起=n,地址=56855
之后,你可以连接到远程(或本地JVM)并列出指定类的所有示例。2同样,你不能直接将远程对象转换为真实的对象,但是你可以访问远程对象的所有字段,甚至可以调用方法。
下面介绍如何连接到远程JVM并获取VirtualMachine。
获取VirtualMachine后,可以使用classesByName和instances方法获取类的示例。它返回ReferenceType的列表:
下面是一个working example程序,它运行并连接到自身,并列出java. lang. String的所有示例。要运行一个示例,您需要类路径中jdk的tool.jar。
6vl6ewon4#
http://java.sun.com/j2se/1.5.0/docs/guide/jvmti/jvmti.html#IterateOverInstancesOfClass
你可以编写一些本地代码来获得JVMTI指针,然后使用它来迭代给定类的所有示例,如上面的链接所示。你可以从你的Java程序中调用这个本地代码。正如Eli所指出的,从Java6开始,有一个高级的 Package 器可以调用这个称为Java调试接口的接口。它允许您从Java本身进行这样的调用,而不必使用本地代码。
我希望这能有所帮助
冲压件
e1xvtsh35#
我想知道您尝试做的事情是否可以使用BTrace来完成?
nkcskrwz6#
根据我在以前的文章中所了解到的,在Java中没有办法获得一个类的所有示例的列表。反射API做了一些很好的事情,但不是这个特定的事情。
你能做的最好的事情就是持有指向所有对象的指针,但这看起来很淫秽,而且对其他人的程序不起作用。不是很理想吧?