Java Attach机制

一、什么是Attach机制?

简单点说就是jdk的一些工具类提供的一种jvm进程间通信的能力,能让一个进程传命令给另外一个进程,并让它执行内部的一些操作,比如说我们为了让另外一个jvm进程把线程dump出来,那么我们运行了一个jstack的进程,然后给它传了个pid的参数,告诉它要对哪个进程进行线程dump,既然是两个进程,那肯定涉及到进程间通信,以及传输协议的定义,比如要执行什么操作,传了什么参数等等。

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


二、Attach方法小结

1、继承Tool/HotSpotAgent.attach(采用Serviceability Agent,简称SA)

SA(Serviceability Agent)是一个用于分析HotSpot运行时进程和Core文件中数据的工具。它可以attach到Java进程或分析Core文件中的数据,了解加载的class,是一个包含大量Java API和工具的工具集,目前实现只支持“snapshot”式的使用方式。“snapshot”是指不支持在SA保持连接的同时让目标进程运行,就是说无论如何在SA进行attach的时候目标进程都要暂停的(SA在attatch到进程之后,会暂停当前进程的执行,拿到的是进程的一个snapshot,当前进程会在SA断开后继续执行),所以在线上使用这类工具进行dump时无论耗时长短必须要摘流量,否则可能会使服务不可用而带来一些不必要的影响。

SA 在JDK中是以Jar文件的形式提供的,位于JAVA_HOME/lib/sa-jdi.jar ,和一般的Jar文件执行一样。

TBJMap使用了hotspot源码的sa-jdi.jar的sun.jvm.hotspot.HotSpotAgent这个类(其中TBJMap继承了sun.jvm.hotspot.tools.Tool这个类,最终用到的也是HotSpotAgent作为代理agent,也就是使用的是SA)。

HotSpotAgent.attach方法过程分析(linux):

(1)首先通过/proc/[pid]/maps读取elf文件,保存符号表(elf文件除了机器码外,还包含其它额外的信息,如段的加载地址,运行地址,重定位表,符号表等,比bin文件要大,通过gcc编译出来的可执行文件是elf文件);

(2)接着通过保存的符号表读取HotSpotVM中localHotSpotVMStructs和localHotSpotVMTypes等变量的地址;

(3)然后使用ptrace根据变量的地址读取SA需要用到的HotSpotVM中的数据的元信息(类型信息,字段offset,地址等);

(4)最后根据这些元信息就可以读取到目标VM上这些数据的值。

在Linux平台上,attach方法最终是使用了/procptrace来读取目标VM中的数据,ptrace提供了一种使父进程可以监视和控制其它进程的方式,它还能够改变子进程中的寄存器和内核映像,因而可以实现断点调试和系统调用的跟踪(ptrace会使内核暂停当前进程并将控制权交给跟踪进程,使跟踪进程得以察看或者修改被跟踪进程的寄存器,待收集完跟踪信息以后会把控制权交回给当前进程让其继续运行)。 

SA工具的attach和detach分别对应的ptrace方法是:

ptrace(PT_ATTACH, pid, 0, 0);  
ptrace(PT_DETACH, pid, 0, 0);
​​更具体源码分析见:HotSpotAgent.attach源码分析

2、VirtualMachine.attach(Attach到Attach Listener线程后执行有限命令)

jstack和jhipcup的attach使用的是VirtualMachine.attach。

VirtualMachine.attach方法过程分析(linux):

(1)信号机制

JVM启动的时候并不会马上创建Attach Listener线程,而是通过另外一个线程Signal Dispatcher在接收到信号处理请求(如jstack,jmap等)时创建临时socket文件/tmp/.java_pid并创建Attach Listener线程(external process会先发送一个SIGQUIT信号给target VM process,target VM会创建一个Attach Listener线程);

(2)Unix domain socket

Attach Listener线程会通过Unix domain socket与external process建立连接,之后就可以基于这个socket进行通信了。

创建好的Attach Listener线程会负责执行这些命令(从队列里不断取AttachOperation,然后找到请求命令对应的方法进行执行,比如jstack命令,找到 { “threaddump”, thread_dump }的映射关系,然后执行thread_dump方法)并且把结果通过.java_pid文件返回给发送者。

      整个过程中,会有两个文件被创建:

.attach_pid<pid>,external process会创建这个文件,为的是触发Attach Listener线程的创建,因为SIGQUIT信号不是只有external process才会发的,通过这个文件来告诉target VM,有attach请求过来了(如果.attach_pid创建好了,说明Attach Listener线程已经创建成功)。相关代码在LinuxVirtualMachine.java中;

.java_pid<pid>,target VM会创建这个文件,这个是因为Unix domain socket本身的实现机制需要去创建一个文件,通过这个文件来进行IPC。相关代码在attachListener_linux.cpp中。

其中的<pid>都是target VM的pid。

具体更详细的VirtualMachine.attach的源码分析见:VirtualMachine.attach源码分析

     Attach Listener线程命令对应的源码(AttachListener.cpp)如下:

static AttachOperationFunctionInfo funcs[] = {
  { "agentProperties",  get_agent_properties },
  { "datadump",         data_dump },
  { "dumpheap",         dump_heap },
  { "load",             JvmtiExport::load_agent_library },
  { "properties",       get_system_properties },
  { "threaddump",       thread_dump },
  { "inspectheap",      heap_inspection },
  { "setflag",          set_flag },
  { "printflag",        print_flag },
  { "jcmd",             jcmd },
  { NULL,               NULL }
};

3、Perf.getPerf().attach(通过PerfData文件获取信息)

用lsof -p 查看进程打开了哪些文件时,经常可以看到/tmp/hsperfdata_$username/$pid文件,如:

[root@ospdev-qxtjx]# lsof -p 32098 | grep perf
java 32098 root  mem    REG   252,1   32768  934145 /tmp/hsperfdata_root/32098
​该文件其实是一个mmap内存映射文件,JVM用来收集状态数据给其它进程使用的,可以使用-XX:+PerfDisableSharedMem来关闭它,当到达安全点时,JVM会把安全点的相关信息写入到这个文件中去,在使用jstack,jconsole等工具时会读取该文件获取内容来统计信息。

perf attach源码调用过程:

调用rt.jar包的sun.misc.Perf类的attach方法

--->调用对应的perf.cppPerf_Attach方法--->方法里再调用PerfMemory::attach

--->最后通过方法mmap_attach_shared将GC或其他状态相关的数据写入到该mmap内存映射文件(该mmap内存映射文件是在JVM启动时调用PerfMemory::create_memory_region就已经创建好的)。

 jstat,sjk等工具通过访问该mmap内存映射文件,读取到相关的内容,显示在屏幕上。

4、几种命令工具的attach方式的比较

(1)几种attach方式的比较:

几种attach方式的比较

(2)命令工具以及它的所属系列及对应的代码入口:

命令工具以及它的所属系列及对应的代码入口

(3)命令工具以及它所对应的attach方式:

命令工具以及它所对应的attach方式

jmap和jstack的“-F”参数可以把原先VirtualMachine.attach方式强制改为SA attach方式,命令如下:

jmap -F -histo <pid>
jstack -F <pid>
jstack -F -l <pid>


参考文献:

1、JVM源码分析之Attach机制实现完全解读(你假笨)

2、HotSpot Serviceability Agent 实现浅析

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,825评论 4 377
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,887评论 2 308
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 112,425评论 0 255
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,801评论 0 224
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,252评论 3 299
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,089评论 1 226
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,216评论 2 322
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 31,005评论 0 215
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,747评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,883评论 2 255
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,354评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,694评论 3 265
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,406评论 3 246
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,222评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,996评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,242评论 2 287
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 36,017评论 2 281

推荐阅读更多精彩内容

  • Attach是什么 在讲这个之前,我们先来点大家都知道的东西,当我们感觉线程一直卡在某个地方,想知道卡在哪里,首先...
    jerrik阅读 1,078评论 0 1
  • 从JDK6开始引入,除了Solaris平台的Sun JVM支持远程的Attach,在其他平台都只允许Attach到...
    andersonoy阅读 3,365评论 0 3
  • Linux SignalsStandard SignalsLinux supports the standard ...
    andersonoy阅读 609评论 0 0
  • 最近因为需求,这周学习了html的一些内容。整理了下常用的这些标签。
    OSong阅读 146评论 0 0
  • 一件蓝布褂 满头银丝 两只浑浊的眼睛 右手拄着一根拐棍 左手端着葫芦瓢 从远处蹒跚而来 我的大姥姥 爬到树上顽皮的...
    沐叶_93f1阅读 172评论 0 9