一、什么是Attach机制?
二、Attach方法小结
1、继承Tool/HotSpotAgent.attach(采用Serviceability Agent,简称SA)
TBJMap使用了hotspot源码的sa-jdi.jar的sun.jvm.hotspot.HotSpotAgent这个类(其中TBJMap继承了sun.jvm.hotspot.tools.Tool这个类,最终用到的也是HotSpotAgent作为代理agent,也就是使用的是SA)。
在Linux平台上,attach方法最终是使用了/proc和ptrace来读取目标VM中的数据,ptrace提供了一种使父进程可以监视和控制其它进程的方式,它还能够改变子进程中的寄存器和内核映像,因而可以实现断点调试和系统调用的跟踪(ptrace会使内核暂停当前进程并将控制权交给跟踪进程,使跟踪进程得以察看或者修改被跟踪进程的寄存器,待收集完跟踪信息以后会把控制权交回给当前进程让其继续运行)。
SA工具的attach和detach分别对应的ptrace方法是:
ptrace(PT_ATTACH, pid, 0, 0);
ptrace(PT_DETACH, pid, 0, 0);
2、VirtualMachine.attach(Attach到Attach Listener线程后执行有限命令)
jstack和jhipcup的attach使用的是VirtualMachine.attach。
具体更详细的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
perf attach源码调用过程:
调用rt.jar包的sun.misc.Perf类的attach方法
--->调用对应的perf.cpp的Perf_Attach方法--->方法里再调用PerfMemory::attach
--->最后通过方法mmap_attach_shared将GC或其他状态相关的数据写入到该mmap内存映射文件(该mmap内存映射文件是在JVM启动时调用PerfMemory::create_memory_region就已经创建好的)。
jstat,sjk等工具通过访问该mmap内存映射文件,读取到相关的内容,显示在屏幕上。
4、几种命令工具的attach方式的比较
(1)几种attach方式的比较:
(2)命令工具以及它的所属系列及对应的代码入口:
(3)命令工具以及它所对应的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 实现浅析