来自:《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. 排序算法(java版)

    一直想理解一下基本的排序算法,最近正好在搞java所以就一并了(为了便于理解,这儿都是以从小到大排序为目的) 冒泡排序 也就是比较连续的两个值,如果前面一个值大于后面一个值,则交换. 时间复杂度为O( ...

  2. 虚拟机CentOS6.5网络配置

    不得不说  6.5比7.0麻烦了许多.. 编辑ifcfg配置文件 vi /etc/sysconfig/network-script/ifcfg-eth0 内容如下 DEVICE=eth0 HWADDR ...

  3. LightOJ - 1027 数学期望

    题意:有n扇门,每扇门有一个值x,大于0代表x分钟后出去,小于0代表x分钟后回到原地,求出去的时间的期望 题解:假设出去的总时间为sum1,回来的总时间为sum2,出去的门个数为out,进来的门的个数 ...

  4. Redis 简单介绍(知识整理笔记)

    前言: Redis 介绍:轻量级.Key-Value.内存数据库.支持持久化 Redis 数据结构:string(字符串),hash(哈希),list(列表),set(集合)及 zset (sorte ...

  5. pycharm配置PyQt5,以及创建第一个项目

    认你已经安装好了pycharm,也正确安装了PyQt5 否则,请移步https://www.cnblogs.com/longbigbeard/p/9628102.html来安装PyQt5 下一步,To ...

  6. svn上传文件钩子

    svn钩子 钩子脚本就是shell的写法,钩子就是被某些版本库事件触发的程序. 常用钩子: post-commit:在提交完成成功创建之后执行该钩子.(提交已经完成,不可更改) 更新之后,通过邮件.微 ...

  7. Django 基础 web框架本质

    Web框架本质 我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端. 这样我们就可以自己实现Web框架了. import socket sk ...

  8. LeetCode OJ:Minimum Depth of Binary Tree(二叉树的最小深度)

    Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the shor ...

  9. 图片上传-本地图片转base64+ie8支持+本地预览支持

    最近项目由于flash同学没在了,图片上传只能前端重新做,后台希望用base64数据上传,复用之前接口 问题来了, 1.ie8 不支持canvas转base64 2.本地预览 base64数据,ie8 ...

  10. CH5E02 [IOI1999]花店橱窗[暴力dp]

    众所周知,这个人太菜了,所以她又来切水题了. 显然设计状态表示第$i$朵花放第$j$瓶中的最大价值.然后瞎转移一波是n三方的,加个前缀max变成n方就水过去了. 当然这题可以搜索剪枝的. 虐lyd书上 ...