gpt4 book ai didi

java - 使用JDWP和JVMTI获取Java应用运行信息

转载 作者:搜寻专家 更新时间:2023-11-01 02:18:21 26 4
gpt4 key购买 nike

我们正在开发一个应用程序,用于使用 JDWP 和 JVMTI 获取正在运行的 java 应用程序的信息。 Sun Java 附带 JDWP 的引用实现,因此使用 agentlib -jdwp: 将使用引用实现。我们的目标是研究 JVMTI 并编写 JVMTI 代理以获取特定细节。还创建了一个前端,用户可以使用该前端请求有关正在运行的 Java 应用程序的特定信息。为此,我们必须为 JDWP 编写我们的实现。尽管我们能够编写 JVMTI 代理并使用它从命令行附加到 Java 应用程序。但我们的目的是将此信息发送到另一个 java 进程(前端)。

所以我们有一个 Java 应用程序 - 前端从 JVMTI 代理(后端)查询信息。这些代理应该能够附加到我们要动态检查的正在运行的 Java 应用程序。关于如何做到这一点的任何想法?或者有人以前试过这个吗?

最佳答案

JDK 有一个用于远程/本地调试的内置 Java api ( com.sun.jdi. )。

要快速开始使用该 api,您可以查看 $JDK_DIR\demo\jpda\examples.jar 中的示例。 [ More details ]


由于官方例子不是很清楚,这里是可重用的例子(灵感来自 this blog post ):

VMAcquirer.java(连接管理器)

public class VMAcquirer {

public VirtualMachine connect(String host,int port) throws IOException {
String strPort = Integer.toString(port);
AttachingConnector connector = getConnector();
try {
VirtualMachine vm = connect(connector,host, strPort);
return vm;
} catch (IllegalConnectorArgumentsException e) {
throw new IllegalStateException(e);
}
}

private AttachingConnector getConnector() {
VirtualMachineManager vmManager = Bootstrap.virtualMachineManager();

for (Connector connector : vmManager.attachingConnectors()) {
if("com.sun.jdi.SocketAttach".equals(connector.name()))
return (AttachingConnector) connector;
}
throw new IllegalStateException();
}

private VirtualMachine connect(AttachingConnector connector,String host,String port)
throws IllegalConnectorArgumentsException, IOException {

Map<String, Connector.Argument> args = connector.defaultArguments();
Connector.Argument portArg = args.get("port");
portArg.setValue(port);
Connector.Argument addressArg = args.get("hostname");
addressArg.setValue(host);

return connector.attach(args);
}
}

Monitor.java(实际监控)

class Monitor {
public static void main(String[] args){
VirtualMachine vm = new VMAcquirer().connect("192.168.0.x", 2600);

System.out.println("name="+vm.name()); //Info about the remote VM
System.out.println("description="+vm.description());

EventRequestManager erm = vm.eventRequestManager();
[...] //Send request using erm instance

loopEventQueue(vm); //Start a loop to listen to the events received
}

public static void loopEventQueue(VirtualMachine vm) throws InterruptedException {
EventQueue eventQueue = vm.eventQueue();
while (true) {
EventSet eventSet = eventQueue.remove();
for (Event ev : eventSet) {
if(ev instanceof MethodEntryEvent) {
handleMethodEntryEvent(ev);
}
[...]
}
}
}
}

被监控的应用程序需要

java -Xdebug -Xrunjdwp:transport=dt_socket,address=2600,server=y,suspend=n ...

可通过 JDWP 获得的信息

  • 跟踪方法调用和返回(可能用于分析或记录)
  • 字段值变化
  • VM信息(见示例中的name()和description())
  • 计算表达式以执行任意代码

  • 关于java - 使用JDWP和JVMTI获取Java应用运行信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1920244/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com