在前面的博客中(http://blog.csdn.net/raintungli/article/details/7034005)所提到的信号转发线程,Attach Listener 线程都只是操作socket文件,并没有去执行比如stack 分析,或者heap的分析,真正的工作线程其实是vm thread.
(一)启动vm thread
我们可以看到,在thread.cpp里启动了线程vm thread,在这里我们同时也稍微的略带的讲一下jvm在linux里如何启动线程的。
通常在linux中启动线程,是调用
而在java里却增加了os:create_thread --初始化线程 和os:start_thread--启动线程
我们去看一下jvm里面是如何在linux里做到的
在os_linux.cpp中来看create_thread的方法
继续看java_start方法
首先jvm先设置了当前线程的状态是Initialized, 然后notify所有的线程,
while (osthread->get_state() == INITIALIZED) {
sync->wait(Mutex::_no_safepoint_check_flag);
}
不停的查看线程的当前状态是不是Initialized, 如果是的话,调用了sync->wait()的方法等待。
来看os:start_thread的方法 os.cpp
这时候设置了线程的状态为runnable,但没有notify线程
在 pd_start_thread(thread)中, os_linux.cpp中
这时候我们看到了notify 线程的操作
也就是这时候notify了线程,因为这时候的线程的状态是RUNNABLE, 方法java_start继续往下执行,于是调用了thread->run()的方法
对于线程vm Thread 也就是调用了vmthread::run方法
vmThread.cpp
调用了loop函数,处理了VM_Operation 的queue 关于queue的级别和优先级处理算法:可以参考 另一篇博客:http://blog.csdn.net/raintungli/article/details/6553337
(二)Jstack 运行在vm thread里的VM_Operation
jstack 处理也就是在前面博客所提到的attach Listener 线程所做的 operation
简单看一下类VM_PrintThreads 它 继承了VM_Operation
当调用VMThread::execute()也就是将VM_PrintThreads 放入了_vm_queue中,交给vm thread 处理,对vm thread来说取出queue里的VM_Operation,并且调用doit方法。
在jstack里,attach listener 的线程产生了VM_PrintThreads,VM_PrintJNI,VM_FindDeadlocks 3个operations,交给了vm thread 的线程处理。