Attach API的基本使用
在JVM运行时加载一个Agent的jar包是 java agent 的一种更加灵活的实现方式,通常我们使用如下 API 将 Agent的 jar包 attach 到目标 JVM 上。
import com.sun.tools.attach.*;import java.io.IOException; public class Main {
public static void main(String[] args) {
VirtualMachine vm = null; try {
// 50447是目标JVM进程的PID vm = VirtualMachine.attach("50447"); // 指定Java Agent的jar包路径 String agentPath = "/path/to/your/simple-agent.jar"; vm.loadAgent(agentPath, "agent init"); } catch (Exception e) {
e.printStackTrace(); } finally {
try {
vm.detach(); } catch (IOException e) {
e.printStackTrace(); } } }}
Attach 通信的底层原理
JVM Attach API 的实现主要基于信号和 UNIX 域套接字,接下来详细介绍这两部分。
信号
信号是由Linux内核支持的一种进程间的异步通信机制,也被称为"软中断"。信号由一个进程通过system call发给另一个进程,接受到信号的进程被中断,进而处理一个突发事件。信号最初的目的是用来指定杀死进程的不同方式。
常见信号如下:
信号名称 | 编号 | 描述 |
SIGINT | 2 | 终端中断信号(Ctrl+C) |
SIGQUIT | 3 | 终端退出信号(Ctrl+\),产生进程core dump文件 |
SIGKILL | 9 | 强制杀死信号,应用程序无法忽略或者捕获 |