linux线程分析工具java,Java开源工具在linux上的源码分析(三):执行的线程

在前面的博客中(http://blog.csdn.net/raintungli/article/details/7034005)所提到的信号转发线程,Attach Listener 线程都只是操作socket文件,并没有去执行比如stack 分析,或者heap的分析,真正的工作线程其实是vm thread.

(一)启动vm thread

jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {

...

// Create the VMThread

{ TraceTime timer("Start VMThread", TraceStartupTime);

VMThread::create();

Thread* vmthread = VMThread::vm_thread();

if(!os::create_thread(vmthread, os::vm_thread))

vm_exit_during_initialization("Cannot create VM thread. Out of system resources.");

// Wait for the VM thread to become ready, and VMThread::run to initialize

// Monitors can have spurious returns, must always check another state flag

{

MutexLocker ml(Notify_lock);

os::start_thread(vmthread);

while(vmthread->active_handles() == NULL) {

Notify_lock->wait();

}

}

}

...

}

我们可以看到,在thread.cpp里启动了线程vm thread,在这里我们同时也稍微的略带的讲一下jvm在linux里如何启动线程的。

通常在linux中启动线程,是调用:

intpthread_create((pthread_t *__thread, __const pthread_attr_t *__attr,void*(*__start_routine) (void*),void*__arg));

而在java里却增加了os:create_thread --初始化线程 和os:start_thread--启动线程。

我们去看一下jvm里面是如何在linux里做到的。

在os_linux.cpp中来看create_thread的方法:

bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {

....

intret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);

....

}

继续看java_start方法:

staticvoid*java_start(Thread *thread) {

....

// handshaking with parent thread

{

MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);

// notify parent thread

osthread->set_state(INITIALIZED);

sync->notify_all();

// wait until os::start_thread()

while(osthread->get_state() == INITIALIZED) {

sync->wait(Mutex::_no_safepoint_check_flag);

}

}

// call one more level start routine

thread->run();

return0;

}

首先jvm先设置了当前线程的状态是Initialized, 然后notify所有的线程,

while(osthread->get_state() == INITIALIZED) {

sync->wait(Mutex::_no_safepoint_check_flag);

}

不停的查看线程的当前状态是不是Initialized, 如果是的话,调用了sync->wait()的方法等待。

来看os:start_thread的方法 os.cpp

voidos::start_thread(Thread* thread) {

// guard suspend/resume

MutexLockerEx ml(thread->SR_lock(), Mutex::_no_safepoint_check_flag);

OSThread* osthread = thread->osthread();

osthread->set_state(RUNNABLE);

pd_start_thread(thread);

}

这时候设置了线程的状态为runnable,但没有notify线程。

在 pd_start_thread(thread)中, os_linux.cpp中:

voidos::pd_start_thread(Thread* thread) {

OSThread * osthread = thread->osthread();

assert(osthread->get_state() != INITIALIZED,"just checking");

Monitor* sync_with_child = osthread->startThread_lock();

MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag);

sync_with_child->notify();

}

这时候我们看到了notify 线程的操作,也就是这时候notify了线程,因为这时候的线程的状态是RUNNABLE, 方法java_start继续往下执行,于是调用了thread->run()的方法。

对于线程vm Thread 也就是调用了vmthread::run方法。

vmThread.cpp

voidVMThread::run() {

...

this->loop();

...

}

调用了loop函数,处理了VM_Operation 的queue 关于queue的级别和优先级处理算法:可以参考 另一篇博客:http://blog.csdn.net/raintungli/article/details/6553337

(二)Jstack 运行在vm thread里的VM_Operation

jstack 处理也就是在前面博客所提到的attach Listener 线程所做的 operation

staticjint thread_dump(AttachOperation* op, outputStream* out) {

bool print_concurrent_locks =false;

if(op->arg(0) != NULL && strcmp(op->arg(0),"-l") ==0) {

print_concurrent_locks =true;

}

// thread stacks

VM_PrintThreads op1(out, print_concurrent_locks);

VMThread::execute(&op1);

// JNI global handles

VM_PrintJNI op2(out);

VMThread::execute(&op2);

// Deadlock detection

VM_FindDeadlocks op3(out);

VMThread::execute(&op3);

returnJNI_OK;

}

简单看一下类VM_PrintThreads 它 继承了VM_Operation

classVM_PrintThreads:publicVM_Operation {

private:

outputStream* _out;

bool _print_concurrent_locks;

public:

VM_PrintThreads()                                                { _out = tty; _print_concurrent_locks = PrintConcurrentLocks; }

VM_PrintThreads(outputStream* out, bool print_concurrent_locks)  { _out = out; _print_concurrent_locks = print_concurrent_locks; }

VMOp_Type type()const{returnVMOp_PrintThreads; }

voiddoit();

bool doit_prologue();

voiddoit_epilogue();

};

当调用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 的线程处理。

【系列文章】

【责任编辑:小林 TEL:(010)68476606】

点赞 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值