Java中有没有一种简单的方法来获取特定类的所有对象实例
目前我正在开发一个 Java 代理来收集内存统计信息。借助仪器 API 我可以掌握这些类(并操纵它们)。使用普通 Java,我可以估算每个对象使用的资源。到目前为止,一切都很好。
我现在面临的问题是“如何获取特定类的每个对象实例”。我可以进行字节码操作来获取对象实例,但我希望还有另一个我不知道的 API,可以帮助我实现我的目标,而无需执行如此繁重的侵入性步骤。最后,性能影响应保持在最低限度。有什么想法吗?
Currently I am working on a Java agent to assemble memory stats. With the help of the instrumentation API I can get a hold of the classes (and manipulate them). With plain Java I can get an estimate of the resources used for each object. So far, so good.
The question I am faced with right now is "how to get a hold of every Object instance of a specific class". I can do byte code manipulation in order to get a hold of the object instance, but I was hoping there is another API I am not aware of, helping me to accomplish my goal without such a rather heavy intrusive step. At the end, the performance impact should be kept to a minimum. Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
Eclipse 中的调试器可以 向您展示一个类的所有实例,因此我查看了 Eclipse 的源代码。 Eclipse 使用 Java 调试有线协议 ,它允许您(从 Java 6 开始)查找所请求类的所有实例。如果您想走这条路,请获取 Eclipse 源代码的副本并查看 org.eclipse.jdi.internal.ReferenceTypeImpl 的
instances
方法。更简单的方法是使用 Java 调试接口< /a>.请注意
ReferenceType.instances
方法。我仍然没有弄清楚如何使用 JDI 连接到正在运行的进程以及如何获取
ReferenceType
的实例。 JDK 包含几个示例,所以我'我确信这是可行的。The debugger in Eclipse can show you all the instances of a class, so I looked around Eclipse's sources. Eclipse uses the Java Debug Wire Protocol, which allows you (since Java 6) to look up all the instances of the requested class. If you want to go down this path, grab a copy of Eclipse sources and check out the
instances
method oforg.eclipse.jdi.internal.ReferenceTypeImpl
.A simpler way is to use the Java Debug Interface. Note the
ReferenceType.instances
method.I still haven't figured out how to use JDI to connect to a running process and how to obtain an instance of
ReferenceType
. The JDK contains several examples, so I'm sure it's doable.正如其他答案中所解释的,您可以使用 JDI 协议来做到这一点。 在调试模式下运行 JVM
这很简单:您需要使用--agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=56855
,然后就可以连接到远程(或本地 JVM)并列出指定类的所有实例。此外,您不能直接将远程对象转换为真实对象,但您可以访问远程对象的所有字段,甚至是 cal 方法。
这里如何连接到远程 JVM 并获取 虚拟机。
获得VirtualMachine 后,您可以使用classesByName 和instances 方法获取类的实例。它返回 ReferenceType 的列表:
这是一个运行和连接的程序的工作示例自身并列出 java.lang.String 的所有实例。要运行示例,您需要类路径中 jdk 中的 tool.jar。
As explained in the other answers you can do it by using the JDI protocol. It is rather simple: you need to run the JVM in debug mode using
--agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=56855
after that, you can connect to the remote (or local JVM) and list all instances of the specified class. Also, you cannot directly cast remote objects to the real object but you can access to all the fields of the remote object and even cal methods.
Here how you can connect to remote JVM and get VirtualMachine.
After getting VirtualMachine you can get instances of a class using methods classesByName and instances. It return List of ReferenceType:
Here is a working example of a program than runs and connects to itself and list all instances of a java.lang.String. To run an example you need tool.jar from jdk in you classpath.
当我读到这篇文章时,我想一定有某种方法可以获取此类信息,因为 Java 分析器已经存在。也许这会有所帮助: http://java.sun .com/j2se/1.4.2/docs/guide/jvmpi/jvmpi.html。它描述了 JVM 和探查器代理之间的接口。但如果您确实想用 Java 编写此代码,那么您可能就不那么幸运了。
具体来说,查看这个函数:
When I read this I was thinking that there must be SOME way to get this kind of info, since java profilers exist. Maybe this will help: http://java.sun.com/j2se/1.4.2/docs/guide/jvmpi/jvmpi.html. It describes the interface between the JVM and a profiler agent. But if you were actually looking to write this in Java you may be out of luck.
Specifically, check out this function:
http://java.sun.com/ j2se/1.5.0/docs/guide/jvmti/jvmti.html#IterateOverInstancesOfClass
您可以编写一些本机代码来获取 JVMTI 指针,然后使用它来
迭代给定类的所有实例,如上面的链接所示。
您可以从 Java 程序中调用此本机代码。
不过,正如 Eli 指出的那样,从 Java 6 开始,有一个名为 Java 调试接口的高级包装器,它允许您从 Java 本身进行此类调用,而不必使用本机代码。
希望这对
拉姆有帮助
http://java.sun.com/j2se/1.5.0/docs/guide/jvmti/jvmti.html#IterateOverInstancesOfClass
You can write some native code that obtains the JVMTI pointer and then uses it to
iterate over all instances of a given class as shown in the link above.
You can call this native code from your Java program.
As Eli points out though, there is a high level wrapper for this called Java Debug Interface available from Java 6 onwards, which allows you to make such calls from Java itself without having to muck around with native code.
hope this helps
Ram
我想知道您想要做的事情是否可以使用 BTrace?
I wonder if what you are trying to do might be accomplished using BTrace?
根据我在之前的文章中了解到的情况,没有办法获取 Java 中类的所有实例的列表。反射 API 做了一些巧妙的事情,但不是这个特定的事情。
你能做的最好的事情就是保存指向所有对象的指针,但这看起来很淫秽,并且在其他人的程序上不起作用。不理想吧?
From what I've been told in previous posts, there is no way to get a list of all the instances of a class in Java. The reflection API does some neat things but not this specific thing.
The best thing you can do is hold pointers to all objects but that seems obscene and doesn't work on other people's programs. Not ideal eh?