jvm15版本源码阅读之从init_globals之后到初始化结束
- 1 从init_globals之后到宏结束
- 1.1 main_thread->cache_global_variables
- 1.2 HandleMark hm
- 1.3 MutexLocker mu
- 1.4 Threads::add
- 1.5 VMThread::create
- 1.6 Thread* vmthread = VMThread::vm_thread
- 1.7 os::create_thread
- 1.8 os::start_thread
- 1.9 Universe::is_fully_initialized
- 1.10 VMThread::execute(&verify_op)
- 1.11 Arguments::update_vm_info_property
- 1.12 Thread* THREAD = Thread::current()
- 1.13 JvmtiExport::enter_early_start_phase
- 1.14 JvmtiExport::post_early_vm_start
- 1.15 initialize_java_lang_classes
- 1.16 quicken_jni_functions
- 1.17 StubCodeDesc::freeze
- 1.18 set_init_completed
- 1.19 LogConfiguration::post_initialize
- 1.20 Metaspace::post_initialize
- 1.21 HOTSPOT_VM_INIT_END
- 2 宏初始化完成之后的方法
- 2.1 Management::record_vm_init_completed
- 2.2 os::initialize_jdk_signal_support
- 2.3 AttachListener::vm_start
- 2.4 Chunk::start_chunk_pool_cleaner_task
- 2.5 ServiceThread::initializ
- 2.6 CompileBroker::compilation_init_phase1
- 2.7 CompileBroker::compilation_init_phase2
- 2.8 initialize_jsr292_core_classes
- 2.9 call_initPhase2
- 2.10 JvmtiExport::enter_start_phase
- 2.11 JvmtiExport::post_vm_start
- 2.12 call_initPhase3
- 2.13 SystemDictionary::compute_java_loaders
- 2.14 ClassLoader::initialize_module_path
- 2.15 JVMCI::initialize_compiler
- 2.16 JvmtiExport::enter_live_phase
- 2.17 PerfMemory::set_accessible
- 2.18 JvmtiExport::post_vm_initialized
- 2.19 Management::initialize
- 2.20 BiasedLocking::init
- 2.21 call_postVMInitHook
- 2.22 WatcherThread::make_startable
- 2.23 WatcherThread::start
- 2.24 create_vm_timer.end
- 3 总结
之前init_globals的初始化已经分析完了,现在开始分析从其之后到结束的剩下的初始化方法.
1 从init_globals之后到宏结束
1.1 main_thread->cache_global_variables
在堆创建完成后保存全局的一些设置.
1.2 HandleMark hm
针对java线程的代理设置,可以认为是线程的hook.
1.3 MutexLocker mu
互斥锁设置
1.4 Threads::add
保存并记录线程
1.5 VMThread::create
代表vm的线程创建,次线程可以代表jvm.进入该方法
重要的两个方法,一个是new VMThread,一个是new VMOperationQueue
1 new VMThread
进入该构造方法,
关键是其继承了NamedThread类,进入其定义文件,可知其继承了NonJavaThread类,不是java线程
再进一步探究这个非java线程NonJavaThread,
可知其也继承了Thread类,和JavaThread一样,都是Thread的子类,因而也是内核线程.
2 new VMOperationQueue
这个就是vm线程要做的事,具体有
1.6 Thread* vmthread = VMThread::vm_thread
获取新建的vm线程的指针
1.7 os::create_thread
系统创建线程,和之前的main_thread一样,也是绑定到一个内核线程.
1.8 os::start_thread
启动新建的vm线程,此时注意,现在依然还在0号线程内,只是仅仅启动了vm线程而已,同时main_thread虽然创建,但还没有启动
1.9 Universe::is_fully_initialized
判断全局是否初始化完成,此时已完成
1.10 VMThread::execute(&verify_op)
新启动的vm线程第一件要做的事就是确认准备就绪
1.11 Arguments::update_vm_info_property
此时再次更新关于vm的各个设置
1.12 Thread* THREAD = Thread::current()
此时获取的依然是0号线程
1.13 JvmtiExport::enter_early_start_phase
TI报告已开始vm
1.14 JvmtiExport::post_early_vm_start
同上
1.15 initialize_java_lang_classes
根据加载的class文件,初始化各个相关的类并记录其偏移量和引用等各种信息,进入该方法
主要方法是initialize_class,进入该方法
第一步就是解析该类,因为之前已经对类的定义及偏移量有了记录,所以这里就依据此进行解析.
第二步就是初始化,进入该方法
进入initialize_impl方法,这里就是在加载了类后,对其进行的初始化,包括链接,准备,校验等,在方法中已经清晰的标注出来
1.16 quicken_jni_functions
准备启动jni的函数
1.17 StubCodeDesc::freeze
此时stub类的描述已被冻结,不再允许有新的进来
1.18 set_init_completed
设置主体初始化已经完成
1.19 LogConfiguration::post_initialize
日志后置初始化
1.20 Metaspace::post_initialize
元空间后置初始化
1.21 HOTSPOT_VM_INIT_END
宏初始化完成
2 宏初始化完成之后的方法
2.1 Management::record_vm_init_completed
管理套件报告vm初始化完成
2.2 os::initialize_jdk_signal_support
系统初始化jdk的信号支持系统
2.3 AttachListener::vm_start
钩子线程启动,这是附着在vm上的线程,对外提供类似探针的作用
2.4 Chunk::start_chunk_pool_cleaner_task
小块内存池启动清理工作
2.5 ServiceThread::initializ
是负责执行vm的派发任务以及TI的调用请求
2.6 CompileBroker::compilation_init_phase1
编译代理初始化第一阶段,主要关于C1和C2的设置,进入可见
2.7 CompileBroker::compilation_init_phase2
这是第二阶段的设置,只是设置了初始化是否已经完成而已.
2.8 initialize_jsr292_core_classes
初始化jsr292的核心类
2.9 call_initPhase2
系统的调用,主要是模块系统的后置初始化,进入可见
2.10 JvmtiExport::enter_start_phase
TI报告已进入开始阶段
2.11 JvmtiExport::post_vm_start
TI报告vm已经启动
2.12 call_initPhase3
第三阶段调用的初始化,主要是加载加密和系统的类加载器等
2.13 SystemDictionary::compute_java_loaders
此时所有的类加载器已经加载完毕,包括bootstrap和系统类加载器,这里计算所有的加载器
2.14 ClassLoader::initialize_module_path
确定模块加载路径
2.15 JVMCI::initialize_compiler
编译接口初始化
2.16 JvmtiExport::enter_live_phase
TI报告进入存活阶段
2.17 PerfMemory::set_accessible
永久区设置获取权限
2.18 JvmtiExport::post_vm_initialized
TI报告vm的后置初始化已经完成
2.19 Management::initialize
管理套件初始化
2.20 BiasedLocking::init
偏向锁初始化
2.21 call_postVMInitHook
Vm后置初始化的回调设置
2.22 WatcherThread::make_startable
监控线程设置为可执行
2.23 WatcherThread::start
监控线程启动
2.24 create_vm_timer.end
创建并初始化vm的过程计时结束,也标志着vm完成启动完成.
3 总结
至此,关于创建和初始化jvm的逻辑已全部执行完毕.整体流程可以归纳如下:
1 首先初始化os相关的设置
2 创建main_thread线程,但是并没有启动
3 根据class文件初始化各个元素
4 初始化堆,利用一个随机数来设定堆的起始位置,再对齐
5 创建vm线程,代表着jvm虚拟机
6 vm的后置初始化,启动钩子线程和监控线程
7 初始化结束,只待进入main方法开始执行
虚拟机毕竟都不简单,但是jvm已经把整个设计降到了比较简化的程度,各个部分很清晰,分析起来也没什么大的难点.