JDK attach API
从 JDK 1.6 开始, Sun 引入了 attach API, 可以 attach 到目标 Java 进程, 这样就可以和目标 JVM 通信, 建立通信之后, 你可以让目标进程加载某些 agent 代码, 这样你就可以和目标进程进行信息交换了.
最简单的代码就在 API 文档里: https://docs.oracle.com/javase/8/docs/jdk/api/attach/spec/index.html
要使用 attach API, 需要引入 jdk lib 目录下的 tools.jar, 因为里面包含包: com.sun.tools.attach.*.
一旦获得 VirtualMachine, 最简单可以获得目标进程的系统属性. 其他的都是通过让目标进程加载 agent 来获得. agent 分为两类: 一类是通过 java.lang.instrument API 写的 Java agent. 另外一类是通过 Native 代码 JVM TI (The agent must be written in native code) 写的 agent.
有人封装的 attach API: https://github.com/gridkit/jvm-attach
比如有人做的工具: https://github.com/aragozin/jvm-tools
如何写 Java Agent : https://docs.oracle.com/javase/8/docs/api/index.html?java/lang/instrument/package-summary.html
如何写基于 JVMTI 的 agent: https://www.oracle.com/technical-resources/articles/javase/jvmti.html
我写的使用 Attach API 和 Instrument API 的agent: https://github.com/manecocomph/myJavaAgent
其它相关概念:
JPDA (Java™ Platform Debugger Architecture), JVM TI, JDWP(Java Debug Wire Protocol), JDI(Java Debug Interface), Java Agent, HPROF agent, HPROF format, BCI (Byte Code Injection), Instrument API, Java Attach API, AsyncGetCallTrace.
JDI API: https://docs.oracle.com/javase/6/docs/jdk/api/jpda/jdi/index.html
使用 JDI 获得一个类的所有实例对象: https://docs.oracle.com/javase/6/docs/jdk/api/jpda/jdi/com/sun/jdi/ReferenceType.html#instances(long)