Mir*_*ahn 17 java profiling jvm
目前我正在使用Java代理来组装内存统计信息.在instrumentation API的帮助下,我可以获得类(并操纵它们).使用普通Java,我可以估计每个对象使用的资源.到现在为止还挺好.
我现在面临的问题是"如何掌握特定类的每个Object实例".我可以进行字节代码操作以获取对象实例,但我希望有另一个我不知道的API,帮助我实现我的目标,没有这么大的侵入性步骤.最后,应将性能影响保持在最低限度.有任何想法吗?
Eli*_*kan 21
Eclipse中的调试器可以向您显示类的所有实例,因此我查看了Eclipse的源代码.Eclipse使用Java Debug Wire Protocol,它允许您(从Java 6开始)查找所请求类的所有实例.如果您想沿着这条路走下去,请获取Eclipse源代码的副本并查看instances方法org.eclipse.jdi.internal.ReferenceTypeImpl.
一种更简单的方法是使用Java调试接口.注意ReferenceType.instances方法.
我还没有弄清楚如何使用JDI连接到正在运行的进程以及如何获取实例ReferenceType.JDK包含几个例子,所以我确信它是可行的.
正如其他答案中所解释的,您可以使用 JDI 协议来做到这一点。这很简单:您需要使用以下命令在调试模式下运行 JVM
--agentlib:jdwp=传输=dt_socket,服务器=y,挂起=n,地址=56855
之后,您可以连接到远程(或本地 JVM)并列出指定类的所有实例。此外,您不能直接将远程对象转换为真实对象,但您可以访问远程对象的所有字段,甚至是 cal 方法。
这里介绍如何连接到远程 JVM 并获取VirtualMachine。
private static VirtualMachine attach(String hostname, String port) throws IOException, IllegalConnectorArgumentsException {
//getSocketAttaching connector to connect to other JVM using Socket
AttachingConnector connector = Bootstrap.virtualMachineManager().attachingConnectors()
.stream().filter(p -> p.transport().name().contains("socket"))
.findFirst().get();
//set the arguments for the connector
Map<String, Argument> arg = connector.defaultArguments();
arg.get("hostname").setValue(hostname);
arg.get("port").setValue(port);
//connect to remote process by socket
return connector.attach(arg);
}
Run Code Online (Sandbox Code Playgroud)
获得VirtualMachine 后,您可以使用classesByName 和instances 方法获取类的实例。它返回ReferenceType的列表:
VirtualMachine vm = attach("localhost", "56856");
//get all classes of java.lang.String. There would be only one element.
List<ReferenceType> classes = vm.classesByName("java.lang.String");
//get all instances of a classes (set maximum count of instannces to get).
List<ObjectReference> o = classes.get(0).instances(100000);
//objectReference holds referenct to remote object.
for (ObjectReference objectReference : o) {
try {
//show text representation of remote object
System.out.println(objectReference.toString());
} catch (com.sun.jdi.ObjectCollectedException e) {
//the specified object has been garbage collected
//to avoid this use vm.suspend() vm.resume()
System.out.println(e);
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个程序的工作示例,该程序运行并连接到自身并列出 java.lang.String 的所有实例。要运行示例,您需要类路径中 jdk 中的 tool.jar。
| 归档时间: |
|
| 查看次数: |
13572 次 |
| 最近记录: |