来自:《Java Performance》第3章 JVM Overview

The HotSpot VM’s implementation of the JNI_CreateJavaVM method performs the following sequence of operations when it is called during the launch of the HotSpot VM.

1. Ensure no two threads call this method at the same time and only one HotSpot VM instance is created in the process. Because the HotSpot VM creates static data structures that cannot be reinitialized, only one HotSpot VM can be created in a process space
once a certain point in initialization is reached. To the engineers who develop the HotSpot VM this stage of launching a HotSpot VM is referred to as the “point of no return.”

2. Check to make sure the Java Native Interface version is supported, and the output stream is initialized for garbage collection logging.

3. The OS modules are initialized such as the random number generator, the current process id, high-resolution timer, memory page sizes, and guard pages. Guard pages are no-access memory pages used to bound memory region accesses. For example, often operating
systems put a guard page at the top of each thread stack to ensure references off the end of the stack region are trapped.

4. The command line arguments and properties passed in to the JNI_CreateJavaVM method are parsed and stored for later use.

5. The standard Java system properties are initialized, such as java.version, java.vendor, os.name, and so on.

6. The modules for supporting synchronization, stack, memory, and safepoint pages are initialized.

7. Libraries such as libzip, libhpi, libjava, and libthread are loaded.

8. Signal handlers are initialized and set.

9. The thread library is initialized.

10. The output stream logger is initialized.

11. Agent libraries (hprof, jdi), if any are being used, are initialized and started.

12. The thread states and the thread local storage, which holds thread specific data required for the operation of threads, are initialized.

13. A portion of the HotSpot VM global data is initialized such as the event log, OS synchronization primitives, perfMemory (performance statistics memory), and chunkPool (memory allocator).

14. At this point, the HotSpot VM can create threads. The Java version of the main thread is created and attached to the current operating system thread. However, this thread is not yet added to the known list of threads.

15. Java level synchronization is initialized and enabled.

16. bootclassloader, code cache, interpreter, JIT compiler, Java Native Interface, system dictionary, and universe are initialized.

17. The Java main thread is now added to the known list of threads. The universe, a set of required global data structures, is sanity  checked. The HotSpot VMThread, which performs all the HotSpot VM’s critical functions, is created. At this point the appropriate
JVMTI events are posted to notify the current state of the HotSpot VM.

18. The following Java classes java.lang.String, java.lang.System, java.lang.Thread, java.lang.ThreadGroup, java.lang.reflect.Method, java.lang.ref.Finalizer, java.lang.Class, and the rest of the Java System classes are loaded and initialized. At this point,
the HotSpot VM is initialized and operational, but not quite fully functional.

19. The HotSpot VM’s signal handler thread is started, the JIT compiler is initialized, and the HotSpot’s compile broker thread is started. Other HotSpot VM helper threads such as watcher threads and stat sampler are started.
At this time the HotSpot VM is fully functional.

20. Finally, the JNIEnv is populated and returned to the caller and the HotSpot VM is ready to service new JNI requests.

对应OpenJDK中的源码:

_JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args) {
HS_DTRACE_PROBE3(hotspot_jni, CreateJavaVM__entry, vm, penv, args); jint result = JNI_ERR;
DT_RETURN_MARK(CreateJavaVM, jint, (const jint&)result); // We're about to use Atomic::xchg for synchronization. Some Zero
// platforms use the GCC builtin __sync_lock_test_and_set for this,
// but __sync_lock_test_and_set is not guaranteed to do what we want
// on all architectures. So we check it works before relying on it.
#if defined(ZERO) && defined(ASSERT)
{
jint a = 0xcafebabe;
jint b = Atomic::xchg(0xdeadbeef, &a);
void *c = &a;
void *d = Atomic::xchg_ptr(&b, &c);
assert(a == (jint) 0xdeadbeef && b == (jint) 0xcafebabe, "Atomic::xchg() works");
assert(c == &b && d == &a, "Atomic::xchg_ptr() works");
}
#endif // ZERO && ASSERT // At the moment it's only possible to have one Java VM,
// since some of the runtime state is in global variables. // We cannot use our mutex locks here, since they only work on
// Threads. We do an atomic compare and exchange to ensure only
// one thread can call this method at a time // We use Atomic::xchg rather than Atomic::add/dec since on some platforms
// the add/dec implementations are dependent on whether we are running
// on a multiprocessor, and at this stage of initialization the os::is_MP
// function used to determine this will always return false. Atomic::xchg
// does not have this problem.
if (Atomic::xchg(1, &vm_created) == 1) {
return JNI_ERR; // already created, or create attempt in progress
}
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"); /**
* Certain errors during initialization are recoverable and do not
* prevent this method from being called again at a later time
* (perhaps with different arguments). However, at a certain
* point during initialization if an error occurs we cannot allow
* this function to be called again (or it will crash). In those
* situations, the 'canTryAgain' flag is set to false, which atomically
* sets safe_to_recreate_vm to 1, such that any new call to
* JNI_CreateJavaVM will immediately fail using the above logic.
*/
bool can_try_again = true; result = Threads::create_vm((JavaVMInitArgs*) args, &can_try_again);
if (result == JNI_OK) {
JavaThread *thread = JavaThread::current();
/* thread is thread_in_vm here */
*vm = (JavaVM *)(&main_vm);
*(JNIEnv**)penv = thread->jni_environment(); // Tracks the time application was running before GC
RuntimeService::record_application_start(); // Notify JVMTI
if (JvmtiExport::should_post_thread_life()) {
JvmtiExport::post_thread_start(thread);
}
// Check if we should compile all classes on bootclasspath
NOT_PRODUCT(if (CompileTheWorld) ClassLoader::compile_the_world();)
// Since this is not a JVM_ENTRY we have to set the thread state manually before leaving.
ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native);
} else {
if (can_try_again) {
// reset safe_to_recreate_vm to 1 so that retrial would be possible
safe_to_recreate_vm = 1;
} // Creation failed. We must reset vm_created
*vm = 0;
*(JNIEnv**)penv = 0;
// reset vm_created last to avoid race condition. Use OrderAccess to
// control both compiler and architectural-based reordering.
OrderAccess::release_store(&vm_created, 0);
} NOT_PRODUCT(test_error_handler(ErrorHandlerTest));
return result;
}

HotSpotVM创建过程(JNI_CreateJavaVM)详解的更多相关文章

  1. brctl创建虚拟网卡详解

    brctl创建虚拟网卡详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 很久之前我分享过一篇关于搭建Openvpn的笔记,在笔记的最后我分享了一个脚本,是用来创建虚拟网卡的,今天 ...

  2. 【Big Data - Hadoop - MapReduce】通过腾讯shuffle部署对shuffle过程进行详解

    摘要: 通过腾讯shuffle部署对shuffle过程进行详解 摘要:腾讯分布式数据仓库基于开源软件Hadoop和Hive进行构建,TDW计算引擎包括两部分:MapReduce和Spark,两者内部都 ...

  3. Tomcat启动过程原理详解 -- 非常的报错:涉及了2个web.xml等文件的加载流程

    Tomcat启动过程原理详解 发表于: Tomcat, Web Server, 旧文存档 | 作者: 谋万世全局者 标签: Tomcat,原理,启动过程,详解 基于Java的Web 应用程序是 ser ...

  4. Ubuntu 16.04.3 Server 版安装过程图文详解

    Ubuntu 16.04.3 Server 版安装过程图文详解 首先,我们会进入系统安装的第一个界面,开始系统的安装操作.每一步的操作,左下角都会提示操作方式! 1.选择系统语言-English2.选 ...

  5. web.xml的加载过程配置详解

      一:web.xml加载过程 简单说一下,web.xml的加载过程.当我们启动一个WEB项目容器时,容器包括(JBoss,Tomcat等).首先会去读取web.xml配置文件里的配置,当这一步骤没有 ...

  6. VMware创建虚拟机教程详解及问题解决

    关于VMware Workstation Pro虚拟机创建教程,本教程主要详细描述使用软件VMware Workstation Pro建虚拟系统过程中步骤详解,以及个人安装时所出现部分问题的解决方案. ...

  7. Linux进程上下文切换过程context_switch详解--Linux进程的管理与调度(二十一)

    1 前景回顾 1.1 Linux的调度器组成 2个调度器 可以用两种方法来激活调度 一种是直接的, 比如进程打算睡眠或出于其他原因放弃CPU 另一种是通过周期性的机制, 以固定的频率运行, 不时的检测 ...

  8. 【转】VS2013动态库文件的创建及其使用详解

    一.VS2013动态库文件的创建 1.新建项目,win32,win32项目,输入项目名称,例如MakeDll. 2.”确定“——”下一步“,选择”DLL“选项,再点”完成“: 3.菜单栏选择”项目“— ...

  9. XML解析之SAX解析过程代码详解

    上一篇谢了解析原理和过程,这里应用代码直观认识这个原理: 新建Demo1类: import java.io.File; import javax.xml.parsers.SAXParser; impo ...

随机推荐

  1. review06

    使用关键字interface来定义一个接口.接口的定义和类定义很相似,分为接口声明和接口体. 接口体中包含常量的声明(没有变量)和抽象方法两部分.接口中只有抽象方法,没有普通方法.而且接口体中所有的常 ...

  2. jsp中的taglib

    JSP中使用Taglib 标准的JSP标记可以调用JavaBeans组件或者执行客户的请求,这大大降低了JSP开发的复杂度和维护量.JSP技术也允许你自定义的taglib,其实换句话说,taglib可 ...

  3. ActiveMq 高级特性的使用

    消费者的 destination 可以使用 wildcards 生产者的 destination 可以使用 composite destinations VirtualTopic 真是一大利器,当初读 ...

  4. 2017-02-20 注册.Net Framework4.0

    在使用IIS发布Web应用程序时,有时会遇到Asp.Net 4.0尚未在Web服务器上注册的问题,需要手动注册下.Net Framework 4.0. 注册.net Framwork4.0 步骤,以w ...

  5. Handsontable 的数据保存(增删改查+导出excel)

    项目用到handsontable 插件 根据官网 API写的handsontable初始化, 数据展示, ajax请求, 参数封装, Controller参数接受 全局容器 var AllData = ...

  6. SSM整合(spring、springMVC、mybatis)

    需要用的包: 包括:spring的包.springMVC的包.mybatis的包.数据库驱动包.json相关的包 配置如下,首先是mybatis的配置 <?xml version="1 ...

  7. EmbarrassedBird网站

    试想现在有如下情景 (情景1) 你写了一封情书准备给心中暗恋很久很久的小Z同学, 我们假设, 你提起来超级无敌巨大的勇气把情书直接交给了小Z, 现在有两种情况 a. 小Z也喜欢你, 欢乐大结局! b. ...

  8. 常用集合ArrayList浅度解析

    首先,先看一下java中对ArrayList的定义代码: public class ArrayList<E> extends AbstractList<E> implement ...

  9. CATransform3D 矩阵变换之立方体旋转实现细节 (转)

    原文地址 http://blog.csdn.net/ch_soft/article/details/7351896 第一部分.前几天做动画,使用到了CATransform3D ,由于没有学过计算机图形 ...

  10. JSON格式规范总结

    JSON有三类元素: 1.结构体(关键字:大括号)2.键值对(关键字:冒号)3.数组(关键字:中括号) 组织规则:结构体中放一个或者多个键值对.键只能是字符串.值可以是:字符串.数字.null.tru ...