【Hotspot】JVM启动流程

HotSpot的组成包括:
 
1.类加载器子系统:负责加载二进制字节码文件流。
2.内存模型:Java栈,本地方法栈,Java堆,方法区,PC寄存器,直接内存
3.垃圾收集器:主要负责Java堆空间内存回收。
4.类文件解析器:解析二进制流字节码文件为对象模型
5.对象模型:虚拟机内部klass-Oop模型
6.解释器:虚拟机内部字节码执行单元,包括字节码解释器,模板解释器
7.编译器:虚拟机内置编译器,字节码指令的动态优化,包括JIT, AOT
8.监控: 虚拟机对外提供的运行时统计监控
9.运行时:虚拟机运行时环境
10.服务:虚拟机内部服务,包括内存,线程,运行时,类加载服务
11.os模块:负责与具体的寄生系统交互
总体调用一些重要函数如下:
jdk/src/share/bin/main.c    =>     程序入口
jdk/src/share/bin/java.c JLI_Launch()
jdk/src/solaris/bin/java_md_solinux.c LoadJavaVM()     =>     加载libjvm动态链接库 jvmpath=/libjvm.so
jdk/src/solaris/bin/java_md_solinux.c JVMInit()     =>     调用ContinueInNewThread创建一个新线程来执行JavaMain
jdk/src/share/bin/java.c ContinueInNewThread()     =>     继续调用ContinueInNewThread0入口
jdk/src/solaris/bin/java_md_solinux.c ContinueInNewThread0()     =>     调用pthread_create创建新线程,启动JavaMain入口
jdk/src/share/bin/java.c JavaMain()     =>     真正的jvm初始化入口
jdk/src/share/bin/java.c InitializeJVM()     =>     初始化jvm,调用CreateJavaVM进行初始化,调用libjvm中的库函数JNI_CreateJavaVM
hotspot/src/share/vm/prims/jni.cpp JNI_CreateJavaVM()     =>     进入jvm初始化阶段,Threads::create_vm()执行入口
hotspot/src/share/vm/runtime.c Threads::create_vm()     =>     jvm初始化入口
hotspot/src/share/vm/utilities.ostream.cpp ostream_init()     =>     输入输出流初始化
hotspot/src/share/vm/runtime/arguments.cpp process_sun_java_launcher_properties
hotspot/src/share/vm/runtime/init.cpp init_globals()     =>     全局模块初始化入口
hotspot/src/share/vm/services/management.cpp management_init()     =>     监控服务,线程服务,运行时服务,类加载服务初始化
hotspot/src/share/vm/interpreter/bytecodes.cpp bytecodes_init()     =>     字节码解释器初始化
hotspot/src/share/vm/classfile/classLoader.cpp classLoader_init()     =>     类加载器初始化第一阶段:zip,jimage入口,设置启动类路径
hotspot/src/share/vm/code/codeCache.cpp codeCache_init()     =>     代码缓存初始化
hotspot/src/share/vm/runtime/vm_version.cpp VM_Version_init()
hotspot/src/share/vm/runtime/os.cpp os_init_globals()
hotspot/src/share/vm/runtime/stubRoutines.cpp stubRoutines_init1()
hotspot/src/share/vm/memory.universe.cpp universe_init()     =>     堆空间,元空间,AOTLoader,SymbolTable,StringTable,G1收集器初始化
hotspot/src/share/vm/interpreter/interpreter.cpp interpreter_init()     =>     模板解释器初始化
hotspot/src/share/vm/intepreter/invocationCounter.cpp invocationCounter_init()     =>     热点统计初始化
hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp marksweep_init()     =>     标记清除GC初始化
hotspot/src/share/vm/utilities/accesssFlags.cpp accessFlags_init()
hotspot/src/share/vm/interpreter/templateTable.cpp templateTable_init()     =>     模板表初始化
hotspot/src/share/vm/runtime/interfaceSupport.cpp InterfaceSupport_init()
hotspot/src/share/vm/runtime/sharedRuntime.cpp SharedRuntime::generate_stubs()     =>     生成部分例程入口
hotspot/src/share/vm/memory/universe.cpp universe2_init() vmSymbols,    =>     系统字典,预加载类,构建基本数据对象模型
hotspot/src/share/vm/memory/referenceProcessor.cpp referenceProcessor_init()     =>     对象引用策略初始化
hotspot/src/share/vm/runtime/jniHandles.cpp jni_handles_init()     =>     JNI引用句柄
hotspot/src/share/vm/code/vtableStubs.cpp vtableStubs_init()     =>     虚表例程初始化
hotspot/src/share/vm/code/icBuffer.cpp InlineCacheBuffer_init()     =>     内联缓冲初始化
hotspot/src/share/vm/complier/complierOracle.cpp compilerOracle_init()    =>      编译器初始化
hotspot/src/share/vm/runtime/compilationPolicy.cpp compilationPolicy_init()     =>     编译策略,根据编译等级确定从c1,c2编译器
hotspot/src/share/vm/complier/complierBroker.cpp compileBroker_init()     =>     编译器初始化
hotspot/src/share/vm/classfile/javaClasses.cpp javaClasses_init()     =>     java基础类相关计算
hotspot/src/share/vm/runtime/stubRoutines.cpp stubRoutines_init1()
jdk/src/share/bin/java.c LoadMainClass()     =>     加载一个类并验证主类是否存在
jdk/src/share/bin/java.c     =>     调用main方法,封装成jni

1.函数  JLI_Launch() 
这个是jvm启动的主函数,加载 libjvm.so,然后调用 JVMInit() 创建新线程去启动 jvm。
调用流程:
jdk/src/share/bin/main.c     =>    程序入口
jdk/src/share/bin/main.c    =>     argv[0]=/jdk/bin/java
jdk/src/share/bin/main.c     =>    argv[1]=Debug
jdk/src/share/bin/main.c     =>    argv[2]=(null)
代码如下:
int JLI_Launch(int argc, char ** argv,              // main.c 的参数
        int jargc, const char** jargv,          // java 参数
        int appclassc, const char** appclassv,  /* app classpath */
        const char* fullversion,                // 版本信息 1.8.0-internal-debug-root_2023_02_07_12_21-b00
        const char* dotversion,                 // 版本信息 1.8
        const char* pname,                      // 执行的程序名称 java、javac 等
        const char* lname,                      // openjdk
        jboolean javaargs,                      /* JAVA_ARGS */
        jboolean cpwildcard,                    /* classpath wildcard*/
        jboolean javaw,                         /* windows-only javaw */
        jint ergo                               /* ergonomics class policy */
){
    // 省略
    if (!LoadJavaVM(jvmpath, &ifn)) {
        return(6);
    }
    // 省略
    // 初始化
    return JVMInit(&ifn, threadStackSize, argc, argv, mode, what, ret);
}

2.函数 LoadJavaVM()
这个用于加载 libjvm,获取里面几个函数在后续初始化虚拟机时进行调用。
调用流程:
jdk/src/share/bin/java.c JLI_Launch()    =>    程序入口
jdk/src/solaris/bin/java_md_solinux.c LoadJavaVM()     =>    加载libjvm动态链接库 jvmpath=libjvm.so
jdk/src/solaris/bin/java_md_solinux.c LoadJavaVM()    =>     获取libjvm库函数 JNI_CreateJavaVM
jdk/src/solaris/bin/java_md_solinux.c LoadJavaVM()     =>    获取libjvm库函数 JNI_GetDefaultJavaVMInitArgs
jdk/src/solaris/bin/java_md_solinux.c LoadJavaVM()     =>    获取libjvm库函数 JNI_GetCreatedJavaVMs
代码如下:
jboolean LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn){
    // 省略
    JLI_TraceLauncher("JVM path is %s\n", jvmpath);
    // 打开libjvm
    libjvm = dlopen(jvmpath, RTLD_NOW + RTLD_GLOBAL);
    // 省略
    ifn->CreateJavaVM = (CreateJavaVM_t)
        dlsym(libjvm, "JNI_CreateJavaVM");
    ifn->GetDefaultJavaVMInitArgs = (GetDefaultJavaVMInitArgs_t)
        dlsym(libjvm, "JNI_GetDefaultJavaVMInitArgs");
    ifn->GetCreatedJavaVMs = (GetCreatedJavaVMs_t)
        dlsym(libjvm, "JNI_GetCreatedJavaVMs");
    return JNI_TRUE;
}

3.函数 JVMInit()
这个函数用于在加载完 libjvm.so 库之后,执行 jvm 初始化的入口,会另外创建一个线程进行初始化。
调用流程:
jdk/src/solaris/bin/java_md_solinux.c JVMInit()     =>    调用ContinueInNewThread创建一个新线程来执行JavaMain
jdk/src/share/bin/java.c ContinueInNewThread()     =>    继续调用ContinueInNewThread0入口
jdk/src/solaris/bin/java_md_solinux.c ContinueInNewThread0()     =>    调用pthread_create创建新线程,启动JavaMain入口
代码如下:
int JVMInit(InvocationFunctions* ifn, jlong threadStackSize,
        int argc, char **argv,
        int mode, char *what, int ret){
    ShowSplashScreen();
    // 创建一个线程去执行jvm初始化
    return ContinueInNewThread(ifn, threadStackSize, argc, argv, mode, what, ret);
}

4.函数 JavaMain ()
到这一步就进入了jvm运行真正的入口。这一步会执行很多操作调用很多子函数,最终加载 java 主类,并使用 jni 调用 java 的静态main函数。
调用流程:
jdk/src/solaris/bin/java_md_solinux.c ContinueInNewThread0()     =>    调用pthread_create创建新线程,启动JavaMain入口
jdk/src/share/bin/java.c JavaMain()    =>     真正的jvm初始化入口
    jdk/src/share/bin/java.c InitializeJVM()     =>    初始化jvm,调用CreateJavaVM进行初始化,调用libjvm中的库函数JNI_CreateJavaVM
    jdk/src/share/bin/java.c LoadMainClass()     =>    加载一个类并验证主类是否存在
    jdk/src/share/bin/java.c     =>    调用main方法,封装成jni,jni_invoke_static() 通过jni解释调用java静态方法
    Debug.java main()    =>     java静态主函数调用
源码如下:
int JNICALL JavaMain(void * _args){
    JavaMainArgs *args = (JavaMainArgs *)_args;
    int argc = args->argc;
    char **argv = args->argv;
    int mode = args->mode;
    char *what = args->what;
    InvocationFunctions ifn = args->ifn;
    JavaVM *vm = 0;
    JNIEnv *env = 0;
    jclass mainClass = NULL;
    jclass appClass = NULL; // actual application class being launched
    jmethodID mainID;
    jobjectArray mainArgs;
    int ret = 0;
    jlong start, end;
    RegisterThread();
    // 调用虚拟机初始化
    start = CounterGet();
    if (!InitializeJVM(&vm, &env, &ifn)) {
        JLI_ReportErrorMessage(JVM_ERROR1);
        exit(1);
    }
    if (showSettings != NULL) {
        ShowSettings(env, showSettings);
        CHECK_EXCEPTION_LEAVE(1);
    }
    if (printVersion || showVersion) {
        PrintJavaVersion(env, showVersion);
        CHECK_EXCEPTION_LEAVE(0);
        if (printVersion) {
            LEAVE();
        }
    }
    /* If the user specified neither a class name nor a JAR file */
    if (printXUsage || printUsage || what == 0 || mode == LM_UNKNOWN) {
        PrintUsage(env, printXUsage);
        CHECK_EXCEPTION_LEAVE(1);
        LEAVE();
    }
    FreeKnownVMs();  /* after last possible PrintUsage() */
    if (JLI_IsTraceLauncher()) {
        end = CounterGet();
        JLI_TraceLauncher("%ld micro seconds to InitializeJVM\n",
               (long)(jint)Counter2Micros(end-start));
    }
    /* At this stage, argc/argv have the application's arguments */
    if (JLI_IsTraceLauncher()){
        int i;
        printf("%s is '%s'\n", launchModeNames[mode], what);
        printf("App's argc is %d\n", argc);
        for (i=0; i < argc; i++) {
            printf("    argv[%2d] = '%s'\n", i, argv[i]);
        }
    }
    ret = 1;
    // 加载主类
    mainClass = LoadMainClass(env, mode, what);
    CHECK_EXCEPTION_NULL_LEAVE(mainClass);
    // 在某些情况例如javafx,没有主函数
    appClass = GetApplicationClass(env);
    NULL_CHECK_RETURN_VALUE(appClass, -1);
    // PostJVMInit使用类名作为GUI用途的应用程序名称
    PostJVMInit(env, appClass, vm);
    // 获取方法签名
    mainID = (*env)->GetStaticMethodID(env, mainClass, "main","([Ljava/lang/String;)V");
    CHECK_EXCEPTION_NULL_LEAVE(mainID);
    /* Build platform specific argument array */
    mainArgs = CreateApplicationArgs(env, argv, argc);
    CHECK_EXCEPTION_NULL_LEAVE(mainArgs);
    // 通过jni调用
    (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
    // java函数退出
    ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1;
    LEAVE();
}

5.函数 InitializeJVM()
在运行 jvm 之前会调用这个子函数先初始化jvm,调用CreateJavaVM进行初始化,调用libjvm中的库函数JNI_CreateJavaVM,这部分代码实现就是源码下面hotspot模块了 。
jdk/src/share/bin/java.c InitializeJVM()     =>    初始化jvm,调用CreateJavaVM进行初始化,调用libjvm中的库函数JNI_CreateJavaVM
    hotspot/src/share/vm/prims/jni.cpp JNI_CreateJavaVM() 进入jvm初始化阶段,Threads::create_vm()执行入口
代码如下:
static jboolean InitializeJVM(JavaVM **pvm, JNIEnv **penv, InvocationFunctions *ifn) {
    // 省略
    // 调用 libjvm.so 中的 JNI_CreateJavaVM 创建虚拟机
    r = ifn->CreateJavaVM(pvm, (void **)penv, &args);
    JLI_MemFree(options);
    return r == JNI_OK;
}

6.函数 JNI_CreateJavaVM ()
由hotspot模块实现的jvm创建。
调用流程:
jdk/src/share/bin/java.c InitializeJVM()     =>    初始化jvm,调用CreateJavaVM进行初始化,调用libjvm中的库函数JNI_CreateJavaVM
hotspot/src/share/vm/prims/jni.cpp JNI_CreateJavaVM()      =>    进入jvm初始化阶段,Threads::create_vm()执行入口
代码如下:
_JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args) {
  //通过Atomic::xchg方法修改全局volatile变量vm_created为1,该变量默认为0,如果返回1则说明JVM已经创建完成或者创建中,返回JNI_EEXIST错误码,如果返回0则说明JVM未创建
  if (Atomic::xchg(1, &vm_created) == 1) {
    return JNI_EEXIST;   // already created, or create attempt in progress
  }
  //通过Atomic::xchg方法修改全局volatile变量safe_to_recreate_vm为0,该变量默认为1,如果返回0则说明JVM已经在重新创建了,返回JNI_ERR错误码,如果返回1则说明JVM未创建
  if (Atomic::xchg(0, &safe_to_recreate_vm) == 0) {
    return JNI_ERR;  // someone tried and failed and retry not allowed.
  }
  assert(vm_created == 1, "vm_created is true during the creation");
  bool can_try_again = true;
  //完成JVM的初始化,如果初始化过程中出现不可恢复的异常则can_try_again会被置为false
  result = Threads::create_vm((JavaVMInitArgs*) args, &can_try_again);
  //初始化正常
  if (result == JNI_OK) {
    //获取当前线程,即执行create_vm的线程,也是JNI_CreateJavaVM执行完毕后执行main方法的线程
    JavaThread *thread = JavaThread::current();
    /*JavaVM赋值,main_vm是jni.h中的全局变量,最终实现指向全局变量jni_InvokeInterface */
    *vm = (JavaVM *)(&main_vm);
    //JNIEnv赋值
    *(JNIEnv**)penv = thread->jni_environment();
    // 记录应用的启动时间
    RuntimeService::record_application_start();
    // 通知JVMTI应用启动
    if (JvmtiExport::should_post_thread_life()) {
       JvmtiExport::post_thread_start(thread);
    }
    EventThreadStart event;
    if (event.should_commit()) {
      event.set_javalangthread(java_lang_Thread::thread_id(thread->threadObj()));
      event.commit();
    }
    //根据配置加载类路径中所有的类
    if (CompileTheWorld) ClassLoader::compile_the_world();
    if (ReplayCompiles) ciReplay::replay(thread);
    // win* 系统添加异常处理的wrapper
    CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(test_error_handler);
    CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(execute_internal_vm_tests);
    //设置当前线程的线程状态
    ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native);
  } else {
  //如果create_vm初始化失败
    if (can_try_again) {
      // 如果可以重试则恢复默认值1
      safe_to_recreate_vm = 1;
    }
    //将vm和penv置空,vm_created重置成0
    *vm = 0;
    *(JNIEnv**)penv = 0;
    OrderAccess::release_store(&vm_created, 0);
  }
  return result;
}

7.函数 Threads::create_vm ()
最终进入这里才会真正初始化 jvm 需要的所有东西。
调用流程:
hotspot/src/share/vm/runtime.c Threads::create_vm()     =>    jvm初始化入口
hotspot/src/share/vm/runtime.c is_supported_jni_version()     =>     检测JNI版本
hotspot/src/share/vm/utilities.ostream.cpp ostream_init()      =>    输入输出流初始化
hotspot/src/share/vm/runtime/arguments.cpp process_sun_java_launcher_properties
hotspot/src/share/vm/runtime/init.cpp init_globals()      =>    全局模块初始化入口
hotspot/src/share/vm/services/management.cpp management_init()      =>    监控服务,线程服务,运行时服务,类加载服务初始化
hotspot/src/share/vm/interpreter/bytecodes.cpp bytecodes_init()      =>    字节码解释器初始化
hotspot/src/share/vm/classfile/classLoader.cpp classLoader_init()      =>    类加载器初始化第一阶段:zip,jimage入口,设置启动类路径
hotspot/src/share/vm/code/codeCache.cpp codeCache_init()      =>    代码缓存初始化
hotspot/src/share/vm/runtime/vm_version.cpp VM_Version_init()
hotspot/src/share/vm/runtime/os.cpp os_init_globals()
hotspot/src/share/vm/runtime/stubRoutines.cpp stubRoutines_init1()
hotspot/src/share/vm/memory.universe.cpp universe_init()      =>    堆空间,元空间,AOTLoader,SymbolTable,StringTable,G1收集器初始化
hotspot/src/share/vm/interpreter/interpreter.cpp interpreter_init()      =>    模板解释器初始化
hotspot/src/share/vm/intepreter/invocationCounter.cpp invocationCounter_init()      =>    热点统计初始化
hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp marksweep_init()      =>    标记清除GC初始化
hotspot/src/share/vm/utilities/accesssFlags.cpp accessFlags_init()
hotspot/src/share/vm/interpreter/templateTable.cpp templateTable_init()      =>    模板表初始化
hotspot/src/share/vm/runtime/interfaceSupport.cpp InterfaceSupport_init()
hotspot/src/share/vm/runtime/sharedRuntime.cpp SharedRuntime::generate_stubs()      =>    生成部分例程入口
hotspot/src/share/vm/memory/universe.cpp universe2_init() vmSymbols,     =>    系统字典,预加载类,构建基本数据对象模型
hotspot/src/share/vm/memory/referenceProcessor.cpp referenceProcessor_init()      =>    对象引用策略初始化
hotspot/src/share/vm/runtime/jniHandles.cpp jni_handles_init()      =>    JNI引用句柄
hotspot/src/share/vm/code/vtableStubs.cpp vtableStubs_init()      =>    虚表例程初始化
hotspot/src/share/vm/code/icBuffer.cpp InlineCacheBuffer_init()      =>    内联缓冲初始化
hotspot/src/share/vm/complier/complierOracle.cpp compilerOracle_init()      =>    编译器初始化
hotspot/src/share/vm/runtime/compilationPolicy.cpp compilationPolicy_init()      =>    编译策略,根据编译等级确定从c1,c2编译器
hotspot/src/share/vm/complier/complierBroker.cpp compileBroker_init()      =>    编译器初始化
hotspot/src/share/vm/classfile/javaClasses.cpp javaClasses_init()      =>    java基础类相关计算
hotspot/src/share/vm/runtime/stubRoutines.cpp stubRoutines_init1()

代码如下:
jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
  extern void JDK_Version_init();
  // Check version
  if (!is_supported_jni_version(args->version)) return JNI_EVERSION;
  // 输入输出流初始化
  ostream_init();
  // Process java launcher properties.
  Arguments::process_sun_java_launcher_properties(args);
  // os模块初始化
  os::init();
  // 系统参数初始化
  Arguments::init_system_properties();
  JDK_Version_init();
  Arguments::init_version_specific_system_properties();
  // 参数转换
  jint parse_result = Arguments::parse(args);
  if (parse_result != JNI_OK) return parse_result;
  os::init_before_ergo();
  jint ergo_result = Arguments::apply_ergo();
  if (ergo_result != JNI_OK) return ergo_result;
  if (PauseAtStartup) {
    os::pause();
  }
  // JVM创建时间统计
  TraceVmCreationTime create_vm_timer;
  create_vm_timer.start();
  TraceTime timer("Create VM", TraceStartupTime);
  // Initialize the os module after parsing the args
  jint os_init_2_result = os::init_2();
  if (os_init_2_result != JNI_OK) return os_init_2_result;
  jint adjust_after_os_result = Arguments::adjust_after_os();
  if (adjust_after_os_result != JNI_OK) return adjust_after_os_result;
  // 初始化 TLS
  ThreadLocalStorage::init();
  // Initialize output stream logging
  ostream_init_log();
  // Convert -Xrun to -agentlib: if there is no JVM_OnLoad
  // Must be before create_vm_init_agents()
  if (Arguments::init_libraries_at_startup()) {
    convert_vm_init_libraries_to_agents();
  }
  // Launch -agentlib/-agentpath and converted -Xrun agents
  if (Arguments::init_agents_at_startup()) {
    create_vm_init_agents();
  }
  // Initialize Threads state
  _thread_list = NULL;
  _number_of_threads = 0;
  _number_of_non_daemon_threads = 0;
  // Initialize global data structures and create system classes in heap
  vm_init_globals();
  // 将java主线程附加到系统当前线程上,线程栈基和栈大小
  JavaThread* main_thread = new JavaThread();
  main_thread->set_thread_state(_thread_in_vm);
  main_thread->record_stack_base_and_size();
  main_thread->initialize_thread_local_storage();
  main_thread->set_active_handles(JNIHandleBlock::allocate_block());
  if (!main_thread->set_as_starting_thread()) {
    vm_shutdown_during_initialization(
      "Failed necessary internal allocation. Out of swap space");
    delete main_thread;
    *canTryAgain = false; // don't let caller call JNI_CreateJavaVM again
    return JNI_ENOMEM;
  }
  // Enable guard page *after* os::create_main_thread(), otherwise it would
  // crash Linux VM, see notes in os_linux.cpp.
  main_thread->create_stack_guard_pages();
    //初始化Java级同步子系统
  ObjectMonitor::Initialize() ;
    // 初始化全局模块
  jint status = init_globals();
  if (status != JNI_OK) {
    delete main_thread;
    *canTryAgain = false; // don't let caller call JNI_CreateJavaVM again
    return status;
  }
  // 在 heap 堆创建完成之后调用
  main_thread->cache_global_variables();
  HandleMark hm;
  { MutexLocker mu(Threads_lock);
    Threads::add(main_thread);
  }
  // Any JVMTI raw monitors entered in onload will transition into
  // real raw monitor. VM is setup enough here for raw monitor enter.
  JvmtiExport::transition_pending_onload_raw_monitors();
  // 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();
      }
    }
  }
  assert (Universe::is_fully_initialized(), "not initialized");
  if (VerifyDuringStartup) {
    // Make sure we're starting with a clean slate.
    VM_Verify verify_op;
    VMThread::execute(&verify_op);
  }
  EXCEPTION_MARK;
  // 到这里虚拟机已经初始化成功了,但还未执行任何java的字节码代码
  if (DumpSharedSpaces) {
    MetaspaceShared::preload_and_dump(CHECK_0);
    ShouldNotReachHere();
  }
  JvmtiExport::enter_start_phase();
  // Notify JVMTI agents that VM has started (JNI is up) - nop if no agents.
  JvmtiExport::post_vm_start();
  {
    TraceTime timer("Initialize java.lang classes", TraceStartupTime);
    if (EagerXrunInit && Arguments::init_libraries_at_startup()) {
      create_vm_init_libraries();
    }
    initialize_class(vmSymbols::java_lang_String(), CHECK_0);
    // 初始化 java_lang.System 下面的类
    initialize_class(vmSymbols::java_lang_System(), CHECK_0);
    initialize_class(vmSymbols::java_lang_ThreadGroup(), CHECK_0);
    Handle thread_group = create_initial_thread_group(CHECK_0);
    Universe::set_main_thread_group(thread_group());
    initialize_class(vmSymbols::java_lang_Thread(), CHECK_0);
    oop thread_object = create_initial_thread(thread_group, main_thread, CHECK_0);
    main_thread->set_threadObj(thread_object);
    // 标价java主线程开始运行
    java_lang_Thread::set_thread_status(thread_object,java_lang_Thread::RUNNABLE);
    initialize_class(vmSymbols::java_lang_Class(), CHECK_0);
    initialize_class(vmSymbols::java_lang_reflect_Method(), CHECK_0);
    initialize_class(vmSymbols::java_lang_ref_Finalizer(),  CHECK_0);
    call_initializeSystemClass(CHECK_0);
    JDK_Version::set_runtime_name(get_java_runtime_name(THREAD));
    JDK_Version::set_runtime_version(get_java_runtime_version(THREAD));
    initialize_class(vmSymbols::java_lang_OutOfMemoryError(), CHECK_0);
    initialize_class(vmSymbols::java_lang_NullPointerException(), CHECK_0);
    initialize_class(vmSymbols::java_lang_ClassCastException(), CHECK_0);
    initialize_class(vmSymbols::java_lang_ArrayStoreException(), CHECK_0);
    initialize_class(vmSymbols::java_lang_ArithmeticException(), CHECK_0);
    initialize_class(vmSymbols::java_lang_StackOverflowError(), CHECK_0);
    initialize_class(vmSymbols::java_lang_IllegalMonitorStateException(), CHECK_0);
    initialize_class(vmSymbols::java_lang_IllegalArgumentException(), CHECK_0);
  }
  initialize_class(vmSymbols::java_lang_Compiler(), CHECK_0);
  reset_vm_info_property(CHECK_0);
  quicken_jni_functions();
  if (TRACE_INITIALIZE() != JNI_OK) {
    vm_exit_during_initialization("Failed to initialize tracing backend");
  }
  // 设置标记jvm初始化运行完成
  set_init_completed();
  Metaspace::post_initialize();
  SystemDictionary::compute_java_system_loader(THREAD);
  if (HAS_PENDING_EXCEPTION) {
    vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION));
  }
  JvmtiExport::enter_live_phase();
  os::signal_init();
  if (!DisableAttachMechanism) {
    AttachListener::vm_start();
    if (StartAttachListener || AttachListener::init_at_startup()) {
      AttachListener::init();
    }
  }
  if (!EagerXrunInit && Arguments::init_libraries_at_startup()) {
    create_vm_init_libraries();
  }
  JvmtiExport::post_vm_initialized();
  if (TRACE_START() != JNI_OK) {
    vm_exit_during_initialization("Failed to start tracing backend.");
  }
  if (CleanChunkPoolAsync) {
    Chunk::start_chunk_pool_cleaner_task();
  }
  if (EnableInvokeDynamic) {
    initialize_class(vmSymbols::java_lang_invoke_MethodHandle(), CHECK_0);
    initialize_class(vmSymbols::java_lang_invoke_MemberName(), CHECK_0);
    initialize_class(vmSymbols::java_lang_invoke_MethodHandleNatives(), CHECK_0);
  }
  if (HAS_PENDING_EXCEPTION) {
    vm_exit(1);
  }
  if (Arguments::has_profile())       FlatProfiler::engage(main_thread, true);
  if (MemProfiling)                   MemProfiler::engage();
  StatSampler::engage();
  if (CheckJNICalls)                  JniPeriodicChecker::engage();
  BiasedLocking::init();
  if (JDK_Version::current().post_vm_init_hook_enabled()) {
    call_postVMInitHook(THREAD);
    // The Java side of PostVMInitHook.run must deal with all
    // exceptions and provide means of diagnosis.
    if (HAS_PENDING_EXCEPTION) {
      CLEAR_PENDING_EXCEPTION;
    }
  }
  {
      MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
      WatcherThread::make_startable();
      if (PeriodicTask::num_tasks() > 0) {
          WatcherThread::start();
      }
  }
  os::init_3();
  create_vm_timer.end();
  return JNI_OK;
}

   
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

0x13

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值