来自:《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;
}

最新文章

  1. OSSFS将OSS bucket 挂载到本地文件系统及注意事项
  2. HBase读写路径的工作机制
  3. cocos进阶教程(2)多分辨率支持策略和原理
  4. 转!! Java中如何遍历Map对象的4种方法
  5. CentOS如何分区
  6. Linux User's Manual IOSTAT
  7. Browser 对象
  8. SQL Server 2008 安装指南
  9. WPF 3D 常用类(1)
  10. Android中使用http协议访问网络
  11. MPLS LDP随堂笔记1
  12. python+appium+unittest自动化测试框架环境搭建
  13. 常见设计模式 (python代码实现)
  14. css3 calc()的用法
  15. 为什么阿里巴巴禁止开发人员使用isSuccess作为变量名
  16. input reset 重置时间
  17. MapReduce :基于 FileInputFormat 的 mapper 数量控制
  18. atom插件安装失败解决方法
  19. java web 中 filter 与 servlet的关系
  20. 第五章 mybatis批量更新update

热门文章

  1. Angular各版本和组件下载
  2. Android当下最流行的开源框架总结
  3. Node.js初接触(一)
  4. java: Comparable比较器,定义二叉操作类
  5. FunnelWeb 开源Blog引擎介绍
  6. Android开发中java.lang.RuntimeException: Unable to start activity ComponentInfo{xxx}
  7. UVALive 3635 Pie(二分法)
  8. javascript.history.go();
  9. RedHat5.8 编译内核驱动 合成initrd.img
  10. 幸运数字(数位dp)