构建我自己的探查器,我使用JVMTI API来构建本机库代理.可以使用add参数-agentlib与JVM一起启动此代理程序.此外还有Attach API,它允许将代理注入正在运行的JVM中.我想使用以下代码将此功能实现到我的探查器:
try {
String pid = VirtualMachine.list().get(0).id();
VirtualMachine vm = VirtualMachine.attach(pid);
vm.loadAgentLibrary("agent");
} catch (AgentLoadException e1) {
e1.printStackTrace();
} catch (AgentInitializationException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} catch (AttachNotSupportedException e) {
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
它有什么作用?从所有可用的正在运行的虚拟机(VirtualMachine.list()
)中,我选择第一个,附加到它并尝试将我的代理加载到其中.可以在UNIX系统上找到名为libagent.so的代理,但在尝试加载代理时会引发以下异常:
com.sun.tools.attach.AttachNotSupportedException:
Unable to open socket file:
target process not responding or HotSpot VM not loaded.
Run Code Online (Sandbox Code Playgroud)
查看源代码,抛出此异常,因为它找不到名为的文件.java_pid<pid>
.我没有在文档中找到有关此类文件的大量信息.我经常听说这种文件不再使用,但我正在运行Java 1.6.
我还尝试连接到其他JVM,事实上我保持这个附加过程是动态的,出于测试原因我只是尝试连接到任何JVM.
这是导致异常的代码,取自sun.tools.attach:LinuxVirtualMachine.java:
// Return the socket file for the given process.
// Checks working directory of process for .java_pid<pid>. If not
// found it looks in /tmp.
private String findSocketFile(int pid) {
// First check for a .java_pid<pid> file in the working directory
// of the target process
String fn = ".java_pid" + pid;
String path = "/proc/" + pid + "/cwd/" + fn;
File f = new File(path);
if (!f.exists()) {
// Not found, so try /tmp
path = "/tmp/" + fn;
f = new File(path);
if (!f.exists()) {
return null; // not found
}
}
return path;
}
Run Code Online (Sandbox Code Playgroud)
它说,它从根目录进入/proc/<pid>
目录.看一下JDK7的变更集,似乎他们正在更改代码JDK7 Changeset到LinuxVirtualMachine
kwo*_*son 28
我遇到过同样的问题.
线程"main"中的异常com.sun.tools.attach.AttachNotSupportedException:无法打开套接字文件:目标进程未响应或未加载HotSpot VM
解决方案被发现做了一些沉重的谷歌搜索.
第一个答案来自http://www.jvmmonitor.org/doc/index.html .出现有一个错误:
如果您看到附加消息"无法打开套接字文件:目标进程未响应或未加载Hotspot VM",则您的应用程序未响应创建/tmp/.java_pid1234之类的套接字文件(例如,由于挂起,文件系统权限) ),或者JVM Monitor无法找到创建的套接字文件(例如,由于错误7009828).
然后经过一些搜索后,我在github上找到了另一个工具的对话,该工具具有相同的症状"无法打开套接字文件"(https://github.com/rhuss/jolokia/issues/34):
jgreen:引起:com.sun.tools.attach.AttachNotSupportedException:无法打开套接字文件:目标进程未响应或未加载HotSpot VM
jgreen:对,我有它工作,但只有当lauching与activemq完全相同的用户.root不起作用
最后一块是解决方案.这.attach调用是成功的唯一途径是通过运行调用连接的Java代码相同的用户作为谁拥有运行JVM进程的一个.在我的例子中,它是activemq用户.
System.out.println("HEAP: " + ManagementFactory.getMemoryMXBean().getHeapMemoryUsage());
HEAP: init = 27127296(26491K) used = 3974200(3881K) committed = 26345472(25728K) max = 675086336(659264K)
Run Code Online (Sandbox Code Playgroud)