读书人

Hotspot Internals in Action(三):

发布时间: 2013-03-06 16:20:31 作者: rapoo

Hotspot Internals in Action(3):HelloWorld

1、CreateJavaVM

(见jni.cpp:JNI_CreateJavaVM)

函数原型:

Hotspot Internals in Action(三):HelloWorld

主要代码:

Hotspot Internals in Action(三):HelloWorld

为vm、penv赋值。

这里顺便提一下VM退出的两条退出路径(见/src/share/vm/runtime/thread.cpp):

destroy_vm:called from jni_DestroyJavaVM() when the program falls off the endof main().

vm_exit(): when the program calls System.exit() to return a value or whenthere is a serious error in VM.

The two shutdown paths are not exactly thesame, but they share Shutdown.shutdown() at Java level and before_exit() andVM_Exit op at VM level.

destroy_vm退出流程:

? + Wait until we are the last non-daemon thread to execute

// <-- every thing is still working at this moment -->

? + Call java.lang.Shutdown.shutdown(), which will invoke Java level

// shutdown hooks, run finalizers if finalization-on-exit

? + Call before_exit(), prepare for VM exit

// > run VM level shutdown hooks (they are registered throughJVM_OnExit(),

// currently the only user of this mechanism is File.deleteOnExit())

// > stop flat profiler, StatSampler, watcher thread, CMS threads,

// post thread end and vm death events to JVMTI,

// stop signal thread

? + Call JavaThread::exit(), it will:

// > release JNI handle blocks, remove stack guard pages

// > remove this thread from Threads list

// <-- no more Java code from this thread after this point -->

? + Stop VM thread, it will bring the remaining VM to a safepoint andstop

// the compiler threads at safepoint

// <-- do not use anything that could get blocked by Safepoint -->

? + Disable tracing at JNI/JVM barriers

? + Set _vm_exited flag for threads that are still running native code

? + Delete this thread

? + Call exit_globals()

// > deletes tty

// > deletes PerfMemory resources

? + Return to caller

2、JavaVM

见:/src/share/vm/prims/jni.h

Hotspot Internals in Action(三):HelloWorld

Hotspot Internals in Action(三):HelloWorld

3、JNIEnv

Hotspot Internals in Action(三):HelloWorld

结构体JNINativeInterface_中包含了大量的函数指针(详见jni.h),这些函数包括:

Hotspot Internals in Action(三):HelloWorldHotspot Internals in Action(三):HelloWorld

这些函数指针在jni.cpp中可以见到赋值:

// Structure containing all jni functions

structJNINativeInterface_ jni_NativeInterface = {

NULL, NULL, NULL, NULL,

jni_GetVersion, jni_DefineClass, jni_FindClass,

jni_FromReflectedMethod, jni_FromReflectedField, jni_ToReflectedMethod,

jni_GetSuperclass, jni_IsAssignableFrom, jni_ToReflectedField,

jni_Throw, jni_ThrowNew, jni_ExceptionOccurred,

jni_ExceptionDescribe, jni_ExceptionClear, jni_FatalError,

jni_PushLocalFrame, jni_PopLocalFrame,

jni_NewGlobalRef, jni_DeleteGlobalRef, jni_DeleteLocalRef,

jni_IsSameObject, jni_NewLocalRef, jni_EnsureLocalCapacity,

jni_AllocObject, jni_NewObject,

jni_NewObjectV, jni_NewObjectA,

jni_GetObjectClass, jni_IsInstanceOf,

jni_GetMethodID,

jni_CallObjectMethod, jni_CallObjectMethodV, jni_CallObjectMethodA,

jni_CallBooleanMethod, jni_CallBooleanMethodV,jni_CallBooleanMethodA,

jni_CallByteMethod, jni_CallByteMethodV, jni_CallByteMethodA,

jni_CallCharMethod, jni_CallCharMethodV, jni_CallCharMethodA,

jni_CallShortMethod, jni_CallShortMethodV, jni_CallShortMethodA,

jni_CallIntMethod, jni_CallIntMethodV, jni_CallIntMethodA,

jni_CallLongMethod, jni_CallLongMethodV, jni_CallLongMethodA,

jni_CallFloatMethod, jni_CallFloatMethodV, jni_CallFloatMethodA,

jni_CallDoubleMethod, jni_CallDoubleMethodV,jni_CallDoubleMethodA,

jni_CallVoidMethod, jni_CallVoidMethodV, jni_CallVoidMethodA,

jni_CallNonvirtualObjectMethod, jni_CallNonvirtualObjectMethodV,

jni_CallNonvirtualObjectMethodA, jni_CallNonvirtualBooleanMethod,

jni_CallNonvirtualBooleanMethodV, jni_CallNonvirtualBooleanMethodA,

jni_CallNonvirtualByteMethod, jni_CallNonvirtualByteMethodV,

jni_CallNonvirtualByteMethodA, jni_CallNonvirtualCharMethod,

jni_CallNonvirtualCharMethodV, jni_CallNonvirtualCharMethodA,

jni_CallNonvirtualShortMethod, jni_CallNonvirtualShortMethodV,

jni_CallNonvirtualShortMethodA, jni_CallNonvirtualIntMethod,

jni_CallNonvirtualIntMethodV, jni_CallNonvirtualIntMethodA,

jni_CallNonvirtualLongMethod, jni_CallNonvirtualLongMethodV,

jni_CallNonvirtualLongMethodA, jni_CallNonvirtualFloatMethod,

jni_CallNonvirtualFloatMethodV, jni_CallNonvirtualFloatMethodA,

jni_CallNonvirtualDoubleMethod, jni_CallNonvirtualDoubleMethodV,

jni_CallNonvirtualDoubleMethodA, jni_CallNonvirtualVoidMethod,

jni_CallNonvirtualVoidMethodV, jni_CallNonvirtualVoidMethodA,

jni_GetFieldID,

jni_GetObjectField, jni_GetBooleanField, jni_GetByteField, jni_GetCharField,

jni_GetShortField, jni_GetIntField, jni_GetLongField, jni_GetFloatField,

jni_GetDoubleField,

jni_SetObjectField, jni_SetBooleanField, jni_SetByteField, jni_SetCharField,

jni_SetShortField, jni_SetIntField, jni_SetLongField, jni_SetFloatField,

jni_SetDoubleField,

jni_GetStaticMethodID,

jni_CallStaticObjectMethod, jni_CallStaticObjectMethodV, jni_CallStaticObjectMethodA,

jni_CallStaticBooleanMethod, jni_CallStaticBooleanMethodV, jni_CallStaticBooleanMethodA,

jni_CallStaticByteMethod, jni_CallStaticByteMethodV, jni_CallStaticByteMethodA,

jni_CallStaticCharMethod, jni_CallStaticCharMethodV, jni_CallStaticCharMethodA,

jni_CallStaticShortMethod, jni_CallStaticShortMethodV, jni_CallStaticShortMethodA,

jni_CallStaticIntMethod, jni_CallStaticIntMethodV, jni_CallStaticIntMethodA,

jni_CallStaticLongMethod, jni_CallStaticLongMethodV, jni_CallStaticLongMethodA,

jni_CallStaticFloatMethod, jni_CallStaticFloatMethodV, jni_CallStaticFloatMethodA,

jni_CallStaticDoubleMethod, jni_CallStaticDoubleMethodV, jni_CallStaticDoubleMethodA,

jni_CallStaticVoidMethod, jni_CallStaticVoidMethodV, jni_CallStaticVoidMethodA,

jni_GetStaticFieldID,

jni_GetStaticObjectField, jni_GetStaticBooleanField, jni_GetStaticByteField,

jni_GetStaticCharField, jni_GetStaticShortField, jni_GetStaticIntField,

jni_GetStaticLongField, jni_GetStaticFloatField, jni_GetStaticDoubleField,

jni_SetStaticObjectField, jni_SetStaticBooleanField, jni_SetStaticByteField,

jni_SetStaticCharField, jni_SetStaticShortField, jni_SetStaticIntField,

jni_SetStaticLongField, jni_SetStaticFloatField, jni_SetStaticDoubleField,

jni_NewString, jni_GetStringLength, jni_GetStringChars, jni_ReleaseStringChars,

jni_NewStringUTF, jni_GetStringUTFLength,

jni_GetStringUTFChars, jni_ReleaseStringUTFChars,

jni_GetArrayLength,

jni_NewObjectArray, jni_GetObjectArrayElement, jni_SetObjectArrayElement,

jni_NewBooleanArray, jni_NewByteArray, jni_NewCharArray, jni_NewShortArray,

jni_NewIntArray, jni_NewLongArray, jni_NewFloatArray, jni_NewDoubleArray,

jni_GetBooleanArrayElements, jni_GetByteArrayElements, jni_GetCharArrayElements,

jni_GetShortArrayElements, jni_GetIntArrayElements, jni_GetLongArrayElements,

jni_GetFloatArrayElements, jni_GetDoubleArrayElements,

jni_ReleaseBooleanArrayElements, jni_ReleaseByteArrayElements,

jni_ReleaseCharArrayElements, jni_ReleaseShortArrayElements,

jni_ReleaseIntArrayElements, jni_ReleaseLongArrayElements,

jni_ReleaseFloatArrayElements, jni_ReleaseDoubleArrayElements,

jni_GetBooleanArrayRegion, jni_GetByteArrayRegion, jni_GetCharArrayRegion,

jni_GetShortArrayRegion, jni_GetIntArrayRegion, jni_GetLongArrayRegion,

jni_GetFloatArrayRegion, jni_GetDoubleArrayRegion,

jni_SetBooleanArrayRegion, jni_SetByteArrayRegion, jni_SetCharArrayRegion,

jni_SetShortArrayRegion, jni_SetIntArrayRegion, jni_SetLongArrayRegion,

jni_SetFloatArrayRegion, jni_SetDoubleArrayRegion,

jni_RegisterNatives, jni_UnregisterNatives,

jni_MonitorEnter, jni_MonitorExit,

jni_GetJavaVM,

jni_GetStringRegion, jni_GetStringUTFRegion,

jni_GetPrimitiveArrayCritical, jni_ReleasePrimitiveArrayCritical,

jni_GetStringCritical, jni_ReleaseStringCritical,

jni_NewWeakGlobalRef, jni_DeleteWeakGlobalRef,

jni_ExceptionCheck,

jni_NewDirectByteBuffer, jni_GetDirectBufferAddress, jni_GetDirectBufferCapacity,

// New 1_6 features

jni_GetObjectRefType

};

4、InvocationFunctions

见:/src/share/tools/luancher/java.h

Hotspot Internals in Action(三):HelloWorld

InvocationFunctions中包含了2个函数指针,CreateJavaVM和GetDefaultJavaVMInitArgs,这2个函数将在LoadJavaVM时指定函数定义。在/src/os/posix/launcher/java_md.c中定义了LoadJavaVM函数,函数执行中对2个函数指针进行了指定,如下:

Hotspot Internals in Action(三):HelloWorld

值得注意的是,也正是在LoadJavaVM中,release版本的hotspot在此处会载入libjvm。

Hotspot Internals in Action(三):HelloWorld

那么,JNI_CreateJavaVM和JNI_GetDefaultJavaVMInitArgs在什么时候调用呢?其具体做了哪些事呢?JNI_GetDefaultJavaVMInitArgs的调用要先于CreateJavaVM。

介绍到这里,我们再返回本节的主题:InitializeJVM做了哪些事情?答案就很明了了:调用已准备好的CreateJavaVM函数,即:JNI_CreateJavaVM。通过调用该函数,完成虚拟机的创建。

另外,InitializeJVM中也会打印参数,我们不妨来看看打印了哪些信息:

Hotspot Internals in Action(三):HelloWorld

可见JavaVM args,打印了一些version和JVM参数等信息。

三、HelloWorld的main方法的调用

在JavaMain()中,初始化虚拟机后,将准备调用main class的main method。在上一篇中我们知道,通过env已准备好的函数指针CallStaticVoidMethod,去调用一个static void的方法,即java主程序的main方法。

函数指针变量CallStaticVoidMethod实际指向函数jni_CallStaticVoidMethod,该函数定义在jni.h中:

Hotspot Internals in Action(三):HelloWorld

实际运行时,见jni.cpp:

Hotspot Internals in Action(三):HelloWorld

显然,main方法的调用,与普通的static方法调用,并没有特别对待,仍然是通过jni_invoke_static。jni_invoke_static将通过调用JavaCalls::call()完成指定method的执行。

读书人网 >编程

热点推荐