Java Attach API使用哪种进程间通信机制?

8
我正在尝试查找Java Attach API在主要操作系统上使用的进程间通信机制,但似乎找不到有关底层机制的参考资料。我仅在这里找到了提到Sun公司开发的DOORS进程间通信机制的信息。但我怀疑Windows或Mac是否使用此机制。大多数文章描述了Java Attach API以及如何加载共享库/DLL,但没有说明例如jvisualvm与本地JVM进程之间的通信实际上是如何工作的。 这里提到tools.jarlibattach.so(在Unix系统上)或attach.dll(在Windows上)负责支持Attach API,但我找不到它们内部工作的详细信息。
那么,在每个主流操作系统上,Java Attach API的进程间通信是如何工作的?即Windows、Mac OSX和Linux。

我相信你正在寻找JPDA - Elliott Frisch
我想了解实际底层操作系统机制。例如,在Linux上它使用Unix套接字吗?它使用其他内核机制吗?Windows呢? - jbx
@ElliottFrisch 感谢您给了我正确方向的提示,我相信我找到了答案 http://docs.oracle.com/javase/8/docs/technotes/guides/jpda/conninv.html - jbx
2个回答

8
Java Attach API具有可插拔的提供程序体系结构。动态附加提供程序是针对目标VM的。在Oracle或OpenJDK JVM的情况下,“sun”提供程序负责。该提供程序使用不同的方法,具体取决于操作系统。该协议还支持其他可维护性工具(如jcmd命令)。
对于Linux,它使用以下协议:
  • 收集目标JVM的pid并创建一个flagfile/tmp/.attach_pid%d
  • 向目标JVM发送SIGQUIT信号
  • 如果flag文件存在,则在目标JVM中的信号处理程序将启动附加监听器线程
  • 附加监听器线程将创建一个/tmp/.java_pid%d unix域套接字,并在该套接字上侦听命令
  • 一个典型的命令是load,它告诉目标JVM加载一个代理实现。这是在共享的attachListener.cpp中实现的,并加载了JVMTI代理。

JMX使用的方法是“load”,它加载指定的JVMTI代理,然后通过RMI定期连接。

较旧的Java版本使用java.io.tmpdir甚至是环境定义的临时目录,但对于后续版本,/tmp已经被硬编码。

在Solaris上,使用Door IPC而不是unix域套接字。在Windows上,使用带有命名管道名称的CreateRemoteThread进行引导。

这在此处描述:http://openjdk.java.net/groups/hotspot/docs/Serviceability.html#tattach(我没有检查,但我会期望HP端口使用Linux机制,OpenJDK AIX端口则是如此)。

对于IBM JDK,使用类似的机制(具有更多配置),如此处所述:https://www.ibm.com/support/knowledgecenter/en/SSYKE2_7.0.0/com.ibm.java.win.70.doc/user/attachapi.html


2
顺便提一下,当被监视的JVM在容器中时(具有不同的根和pid命名空间),上述协议将无法工作。目前正在进行修补程序,使附加客户端使用目标的根并解析PID命名空间。 - eckes
你知道这个补丁的状态吗?你能指引我相关的资源吗? - Eytan Naim
2
我一直以为这个问题已经解决了不少时间,但是这里有一个关于它的 bug 看起来还没有被解决。https://bugs.openjdk.java.net/browse/JDK-8228343 - eckes

2
似乎这是在Java平台调试架构(JPDA)之上实现的(正如Elliott Frisch所指示的那样)。
在Windows操作系统上,使用共享内存传输。
在基于Linux的系统上,使用Socket传输。
更多详细信息可以在此处找到。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接