首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

Hotspot Internals in Action(三):HelloWorld

2013-03-06 
Hotspot Internals in Action(3):HelloWorld1、CreateJavaVM(见jni.cpp:JNI_CreateJavaVM)函数原型:主要代

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的执行。

 

 

热点排行