JavaThread类启动过程与main方法调用



    JavaThread对应于每一个java层的Thread,例如调用public static void main(String[] args)时,自动生成一个java线程,而且每new Thread(){()->{}}.start();的时候也会生成一个java线程。



    根据一些粗显的知识,java线程中包含虚拟机栈、程序计数器。



        虚拟机栈包含:栈帧,每一个方法调用都会生成一个栈帧



                                栈帧包含:    局部变量表、操作数栈、动态链接、方法返回地址







    ———————————————————————————————————————————————–



    或许大家作为JAVA程序员想象了一遍又一遍的JVM内部实现,但大部分是错误的想法,(例如 :每一个虚拟机栈包含了局部变量表,但在OpenJDK 的JVM中,虚拟机栈和局部变量表是分离的实现) ,今天我们就来看一下,在JVM中,这些东西是怎么实现的。



    ———————————————————————————————————————————————–



    JavaThread是如何启动并运行的



    JavaThread的启动位于    



        java.c:main -> java.c:javaMain -> java.c:InitializeJVM->Thread.cpp:CreateJavaVM







    JavaThread内部的重要属性如下:



            JavaThread    _next;                                  下一个JavaThread



            oop            _threadObj;                              



            JavaFrameAnchor _anchor;                            JavaFrame的锚点



            ThreadFunction _entry_point;                        



            JNIEnv        _jni_environment;



            vframeArray  _vframe_array_head;                    vframe_array的头部



            vframeArray  _vframe_array_last;                    vframe_array的尾部



            GrowableArray<jvmtiDeferredLocalVariableSet> _deferred_locals_updates;        本地变量表,即localVariable,从此可以看出,本地变量表并非在栈帧中,而是并列的结构



            methodOop     _callee_target;



            oop           _vm_result;



            oop           _vm_result_2;            



            MemRegion     _deferred_card_mark;



            ThreadSafepointState _safepoint_state;



            address               _saved_exception_pc;



            volatile oop     _exception_oop;



            volatile address _exception_pc;



            volatile address _exception_handler_pc;



            volatile int     _exception_stack_size; 



            volatile int     _is_method_handle_return;



            



    ———————————————————————————————————————————————–



            JavaThread main_thread = new JavaThread();



                    调用父构造函数:    Thread()



                                        代码:    new HandleMark(this);



                                        代码:    _unhandled_oops = new UnhandledOops(this);



                    代码:                   initialize();



                                        代码:    _anchor.clear();



                                        代码:    pd_initialize();



                                                    代码:    _anchor.clear();



                    代码:                   _is_attaching = is_attaching;



            main_thread->set_thread_state(_thread_in_vm);



                    线程状态共12种



                        enum JavaThreadState {

                          _thread_uninitialized     =  0, // should never happen (missing initialization)

                          _thread_new               =  2, // just starting up, i.e., in process of being initialized

                          _thread_new_trans         =  3, // corresponding transition state (not used, included for completness)

                          _thread_in_native         =  4, // running in native code

                          _thread_in_native_trans   =  5, // corresponding transition state

                          _thread_in_vm             =  6, // running in VM

                          _thread_in_vm_trans       =  7, // corresponding transition state

                          _thread_in_Java           =  8, // running in Java or in stub code

                          _thread_in_Java_trans     =  9, // corresponding transition state (not used, included for completness)

                          _thread_blocked           = 10, // blocked in vm

                          _thread_blocked_trans     = 11, // corresponding transition state

                          _thread_max_state         = 12  // maximum thread state+1 - used for statistics allocation

                        };

                        



            main_thread->record_stack_base_and_size();



            main_thread->initialize_thread_local_storage();



                    代码:    ThreadLocalStorage::set_thread(this);



                    代码:    os::initialize_thread();        空函数



            main_thread->set_active_handles(JNIHandleBlock::allocate_block());



                    代码:    block = new JNIHandleBlock();



                    代码:    return block;



            main_thread->set_as_starting_thread()



                    代码:    os::create_main_thread((JavaThread)this)



                            代码:    create_attached_thread(thread)



                                    代码:    OSThread osthread = new OSThread(NULL, NULL);



                                    代码:    osthread->set_thread_id(os::Linux::gettid());            //设置线程ID为Linux的gettid,内部代码为系统调用syscall(SYS_gettid);



                                    代码:    osthread->set_pthread_id(::pthread_self());             //设置pthreadId为当前运行的线程id



                                    代码:    os::Linux::init_thread_fpu_state();



                                    代码:    osthread->set_state(RUNNABLE);



                                    代码:    thread->set_osthread(osthread);



                                    代码:    JavaThread jt = (JavaThread )thread;



                                    代码:    address addr = jt->stack_yellow_zone_base();



                                    代码:    osthread->set_expanding_stack();



                                    代码:    os::Linux::manually_expand_stack(jt, addr);



                                    代码:    osthread->clear_expanding_stack();



                                    代码:    os::Linux::hotspot_sigmask(thread);



                            以上代码需要注意的是,在内部并没有调用任何os:create_thread()方法,只是将主线程设置为了osthread的threadId,因此此步骤并未生成新的thread,而是使用原thread继续运行



            main_thread->create_stack_guard_pages();            创建警戒页并把该警戒页通过::mmap函数映射到address low_addr = stack_base() - stack_size();处



            main_thread->cache_global_variables();                空函数



            Threads::add(main_thread);            



                            代码:    p->initialize_queues();



                            代码:    p->set_next(_thread_list);



                            代码:    _thread_list = p;



                            代码:    _number_of_threads++;



                            代码:    ThreadService::add_thread(p, daemon);



            oop thread_object = create_initial_thread(thread_group, main_thread, CHECK_0);



            main_thread->set_threadObj(thread_object);



            java_lang_Thread::set_thread_status(thread_object, java_lang_Thread::RUNNABLE);







            在执行完毕Thread.cpp:CreateJavaVM后,在java.c中



            mainClassName = GetMainClassName(env, jarfile);



            classname = (char )(env)->GetStringUTFChars(env, mainClassName, 0);



            mainClass = LoadClass(env, classname);



            mainID = (env)->GetStaticMethodID(env, mainClass, “main”, ”([Ljava/lang/String;)V”);



            jmethodID mid;



            jobject obj = (env)->ToReflectedMethod(env, mainClass,mainID, JNI_TRUE);



            mid = (env)->GetMethodID(env,(env)->GetObjectClass(env, obj),”getModifiers”, “()I”);



            mods = (env)->CallIntMethod(env, obj, mid);



            (env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);                //执行java的main方法



                    代码:    env->CallStaticVoidMethod( pClass, pMid, pArgs);



                                代码:    functions->CallStaticVoidMethodV(this,cls,methodID,args);



                                            代码:     JavaValue jvalue(T_VOID);



                                                        JNI_ArgumentPusherVaArg ap(THREAD, methodID, args);                    //将参数推送到堆栈中



                                                                调用父类构造函数:    JNI_ArgumentPusher(thread, JNIHandles::resolve_jmethod_id(method_id)->signature())



                                                                            调用父类构造函数:    SignatureIterator(thread, signature)



                                                                                        代码:        _signature       = signature;



                                                                                        代码:        _parameter_index = 0;



                                                                            代码:    this->_return_type = T_ILLEGAL;



                                                                            代码:    _arguments = NULL;



                                                                代码:    set_ap(rap);



                                                                            代码:    _ap = rap;



                                                        jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);        //执行static方法,参数为ap,返回值为jvalue



                                                                代码:    methodHandle method(THREAD, JNIHandles::resolve_jmethod_id(method_id));                                                    



                                                                代码:    ResourceMark rm(THREAD);



                                                                代码:    int number_of_parameters = method->size_of_parameters();



                                                                代码:    JavaCallArguments java_args(number_of_parameters);



                                                                代码:    args->set_java_argument_object(&java_args);



                                                                代码:    args->iterate( Fingerprinter(THREAD, method).fingerprint() );                    //???????????+++++++++++++++



                                                                代码:    result->set_type(args->get_ret_type());



                                                                代码:    JavaCalls::call(result, method, &java_args, CHECK);                                  invoke the method



                                                                            代码:    JavaCalls::call



                                                                                    代码:    JavaCalls::call_helper



                                                                                    代码:    JavaCallWrapper link(method, receiver, result, CHECK);



                                                                                    代码:    address entry_point = method->from_interpreted_entry();



                                                                                    代码:    



                                                                                    代码:    StubRoutines::call_stub()(                                                    调用Stub,在java中,每一个方法都会解析为一个Stub

                                                                                                        (address)&link,

                                                                                                        // (intptr_t)&(result->_value), // see NOTE above (compiler problem)

                                                                                                        result_val_address,          // see NOTE above (compiler problem)

                                                                                                        result_type,

                                                                                                        method(),

                                                                                                        entry_point,

                                                                                                        args->parameters(),

                                                                                                        args->size_of_parameters(),

                                                                                                        CHECK

                                                                                                      );



                                                                                    代码:    result = link.result();



                                                                                    代码:    result->set_jobject((jobject)thread->vm_result());



                                                                                            



                                                                代码:    if (result->get_type() == T_OBJECT || result->get_type() == T_ARRAY) {

                                                                               result->set_jobject(JNIHandles::make_local(env, (oop) result->get_jobject()));

                                                                           }







            ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1;



    至此,可以看到



    java.c中的launcher创建了JVM环境,然后获取到了java的main方法,然后执行jenv->CallStaticVoidMethod函数,触发了jni_invoke_static函数,之后触发了StubRoutines::call_stub()所代表的函数指针








    那么问题来了,StubRoutines是什么东西,是在什么时候产生的?其内部又会对JavaThread的属性产生什么操作?其内部是如何调用到entry_point即method->from_interpreted_entry()的?



    可以阅读一下R大的博客http://hllvm.group.iteye.com/group/topic/37707,权当预习。



    这个行业前辈众多,需要膜拜之……例如R大,在我刚学Java之时他成名已久