searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

JVM的attach技术

2023-08-02 02:20:17
77
0

1、什么是attach技术

Attach机制是JVM提供一种JVM进程间通信的能力,能让一个进程传命令给另外一个进程,并让它执行内部的一些操作。

 

比如:

为了让另外一个JVM进程把线程dump出来,那么首先跑了一个jstack的进程,然后传了个pid的参数,告诉它要哪个进程进行线程dump,既然是两个进程,那肯定涉及到进程间通信,以及传输协议的定义,比如:要执行什么操作,传了什么参数等。

 

2、实现原理

Attach Listener线程

 

在上面的Thread Dump日志中,出现了两个线程:“Attach Listener” 和 “Signal Dispatcher”,这两个线程便是Attach机制的关键。

Attach Listener 线程是负责接收到外部的命令,而对该命令进行执行的并且把结果返回给发送者。

在启动的时候有可能不会创建AttachListener线程,由jvm参数控制:DisableAttachMechanism,StartAttachListener ,ReduceSignalUsage 均默认是 false。

 

那么 在上面Thread Stack日志中看到的AttachListener线程是怎么创建的呢,这个就要关注另外一个线程“Signal Dispatcher”了,顾名思义是处理信号的,这个线程是在JVM启动的时候肯定会创建的。

 

AttachListener线程启动过程

 

一开始会 判断当前进程目录下是否有个.Attach_pid文件,如果没有就会在/tmp下创建一个/tmp/.Attach_pid,当那个文件的uid和自己的uid是一致的情况下(为了安全)再调用init方法。

 

当其创建了一个监听套接字,并创建了一个文件/tmp/.java_pid,这个文件就是客户端之前一直在轮询等待的文件,随着这个文件的生成,意味着Attach的创建过程圆满结束了。

 

AttachListener线程的工作流程

AttachListener线程启动后,会进入for死循环,不停地调用AttachOperation* op = AttachListener::dequeue();获取操作对象。如果进入到AttachListener::dequeue()方法看一看,其实就是在读上边监听的套接字。

 

如上代码中可以看到,如果没有请求的话,会一直accept在那里,当来了请求,然后就会创建一个套接字,并读取数据,构建出LinuxAttachOperation返回,找到请求对应的操作,调用操作得到结果并把结果写到这个socket的文件,如果你把socket的文件删除,jstack/jmap会出现错误信息 unable to open socket file。

 

比如一开始说的jstack命令,找到 { “threaddump”, thread_dump }的映射关系,然后执行thread_dump方法。

 

AttachOperation有很多种类,比如:内存dump,线程dump,类信息统计(比如加载的类及大小以及实例个数等),动态加载agent,动态设置vm flag(但是并不是所有的flag都可以设置的,因为有些flag是在jvm启动过程中使用的,是一次性的),打印vm flag,获取系统属性等,这些对应的源码:

 

Signal Dispatcher 线程

 

在os.cpp中的 signal_init() 函数中,启动了signal dispatcher 线程,对signal dispather线程主要是用于处理信号,等待信号并且分发处理。

0条评论
0 / 1000
廖****兴
5文章数
0粉丝数
廖****兴
5 文章 | 0 粉丝
廖****兴
5文章数
0粉丝数
廖****兴
5 文章 | 0 粉丝
原创

JVM的attach技术

2023-08-02 02:20:17
77
0

1、什么是attach技术

Attach机制是JVM提供一种JVM进程间通信的能力,能让一个进程传命令给另外一个进程,并让它执行内部的一些操作。

 

比如:

为了让另外一个JVM进程把线程dump出来,那么首先跑了一个jstack的进程,然后传了个pid的参数,告诉它要哪个进程进行线程dump,既然是两个进程,那肯定涉及到进程间通信,以及传输协议的定义,比如:要执行什么操作,传了什么参数等。

 

2、实现原理

Attach Listener线程

 

在上面的Thread Dump日志中,出现了两个线程:“Attach Listener” 和 “Signal Dispatcher”,这两个线程便是Attach机制的关键。

Attach Listener 线程是负责接收到外部的命令,而对该命令进行执行的并且把结果返回给发送者。

在启动的时候有可能不会创建AttachListener线程,由jvm参数控制:DisableAttachMechanism,StartAttachListener ,ReduceSignalUsage 均默认是 false。

 

那么 在上面Thread Stack日志中看到的AttachListener线程是怎么创建的呢,这个就要关注另外一个线程“Signal Dispatcher”了,顾名思义是处理信号的,这个线程是在JVM启动的时候肯定会创建的。

 

AttachListener线程启动过程

 

一开始会 判断当前进程目录下是否有个.Attach_pid文件,如果没有就会在/tmp下创建一个/tmp/.Attach_pid,当那个文件的uid和自己的uid是一致的情况下(为了安全)再调用init方法。

 

当其创建了一个监听套接字,并创建了一个文件/tmp/.java_pid,这个文件就是客户端之前一直在轮询等待的文件,随着这个文件的生成,意味着Attach的创建过程圆满结束了。

 

AttachListener线程的工作流程

AttachListener线程启动后,会进入for死循环,不停地调用AttachOperation* op = AttachListener::dequeue();获取操作对象。如果进入到AttachListener::dequeue()方法看一看,其实就是在读上边监听的套接字。

 

如上代码中可以看到,如果没有请求的话,会一直accept在那里,当来了请求,然后就会创建一个套接字,并读取数据,构建出LinuxAttachOperation返回,找到请求对应的操作,调用操作得到结果并把结果写到这个socket的文件,如果你把socket的文件删除,jstack/jmap会出现错误信息 unable to open socket file。

 

比如一开始说的jstack命令,找到 { “threaddump”, thread_dump }的映射关系,然后执行thread_dump方法。

 

AttachOperation有很多种类,比如:内存dump,线程dump,类信息统计(比如加载的类及大小以及实例个数等),动态加载agent,动态设置vm flag(但是并不是所有的flag都可以设置的,因为有些flag是在jvm启动过程中使用的,是一次性的),打印vm flag,获取系统属性等,这些对应的源码:

 

Signal Dispatcher 线程

 

在os.cpp中的 signal_init() 函数中,启动了signal dispatcher 线程,对signal dispather线程主要是用于处理信号,等待信号并且分发处理。

文章来自个人专栏
jvm知识
5 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0