`

OpenJDK源码分析(2)

阅读更多
  
找到jvm.dll之后呢?
——加载。

    也就是获取到应该加载的jvmPath之后,java.c接下来执行到263行:
 
  if (!LoadJavaVM(jvmpath, &ifn)) {
      exit(6);
    }
,通过java_md.c的LoadJavaVM函数来加载整个JVM虚拟机,该方法有2个参数: 第一个是我们之前获取得到的jvm.dll的绝对路径;
     另一个是main函数一开始就初始化的一个结构体InvocationFunctions。

   LoadJVM首先通过LoadLibrary函数加载了jvm.dll,然后把其中的2个方法JNI_CreateJavaVM 和 JNI_GetDefaultJavaVMInitArgs 挂载到参数ifn的结构体中。
/* Load the Java VM DLL */
    if ((handle = LoadLibrary(jvmpath)) == 0) {
        ReportErrorMessage2("Error loading: %s", (char *)jvmpath, JNI_TRUE);
        return JNI_FALSE;
    }

    /* Now get the function addresses */
    ifn->CreateJavaVM =
        (void *)GetProcAddress(handle, "JNI_CreateJavaVM");
    ifn->GetDefaultJavaVMInitArgs =
        (void *)GetProcAddress(handle, "JNI_GetDefaultJavaVMInitArgs");

   
    加载完jvm.dll,接下来main函数继续初始化接收到的所有参数,然后把所有初始化好的jvm参数和之前我们加载好的InvocationFunctions一起赋值给JavaMainArgs
struct JavaMainArgs {
  int     argc;
  char ** argv;
  char *  jarfile;
  char *  classname;
  InvocationFunctions ifn;
};

    构造好JavaMainArgs 之后,会执行到java.c的370行。
ContinueInNewThread(JavaMain, threadStackSize, (void*)&args, ret);
新起一个线程去执行JavaMain函数。
    JavaMain函数经过一系列初始化之后,会调用java.c中的InitializeJVM函数来初始化一个JVM虚拟机,该函数主要执行逻辑就一句话,在java.c的1269行
  r = ifn->CreateJavaVM(pvm, (void **)penv, &args);

    就是通过调用我们之前挂在的InvocationFunctions的CreateJVM创建一个虚拟机,而CreateJVM挂载的是jvm.dll中的JNI_CreateJavaVM方法。JNI_CreateJavaVM方法的源代码在\hotspot\src\share\vm\prims\jni.cpp中。该方法的定义如下:
_JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args)
该方法有3个参数,都是从java.c的InitializeJVM函数传过来的:   第一个参数是javaVM指针的指针;
       第二个参数是JNIEnv类型的指针的指针;
       第三个参数是一个虚拟机的参数的指针。该函数主要的功能
result = Threads::create_vm((JavaVMInitArgs*) args, &can_try_again);
  if (result == JNI_OK) {
    JavaThread *thread = JavaThrad::current();
    /* thread is thread_in_vm heere */
    *vm = (JavaVM *)(&main_vm);
    *(JNIEnv**)penv = thread->jni_environment();

    一是根据jvm启动参数构建一个VM虚拟机;
    二是构建了一个JNIEnv的实例挂载到main中的JNIEnv结构的指针。这样,java.c的InitializeJVM函数就可以使用这个JNIEnv实例继续做下面的操作。
    构造好了VM实例和JNIEnv,JavaMain函数开始加载Class,它首先会寻找java程序的入口类,即MainClass。
if (jarfile != 0) {
        mainClassName = GetMainClassName(env, jarfile);
        .....
    } else {
        mainClassName = NewPlatformString(env, classname);
      ....
    }
如果执行的是jar文件,则会通过GetMainClassName函数查找jar中的MainClass.具体逻辑就是先实例化java/util/jar/JarFile类,然后获取执行的jar文件中的Manifest对象的"Main-Class"属性。——即jar包中的META-INF/MANIFEST.MF文件的"Main-Class"属性。
       如果直接是执行的java类,就直接以该类为MainClass。然后调用GetStaticMethodID函数获MainClass中的public static void main(str[] args)方法,找到MainClass中的入口函数,就会初始化MainClass的参数
 mainArgs = NewPlatformStringArray(env, argv, argc);
,然后调用前面获取到的JNIEnv实例调用CallStaticVoidMethod方法执行入口函数。
/* Invoke main method. */
    (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);

这样,程序才执行到我们自己所写的代码。

    
0
0
分享到:
评论
1 楼 lemoncyb 2012-05-22  
博主分析好清楚啊,受教了。

相关推荐

    openjdk8源码,适合深入学习jdk源码的同学

    openjdk8源码,适合深入学习jdk源码的同学

    OpenJDK源码

    除此之外,OpenJDK源码还包含了丰富的工具集,如javac编译器、jdb调试器、jmap内存分析工具等。这些工具的源码可以帮助开发者了解如何构建和维护复杂的系统工具,同时也可以提升他们对Java平台整体工作流程的理解。 ...

    OpenJdk源码包

    OpenJDK(Open Java Development Kit)是Java开发工具包的一个开源实现,它是Oracle JDK的开源版本,...通过深入研究OpenJDK源码,开发者不仅可以提升自己的Java技术能力,还可以为社区贡献代码,推动Java技术的发展。

    openjdk源码1

    《OpenJDK源码探索——基于openjdk-7u4-fcs-src-b22-02_may_2012》 OpenJDK,全称为Open Source Java Development Kit,是Java开发工具集的一个开源实现,它为Java平台提供了一个开放源代码的实现,包括HotSpot...

    openjdk8完整源码

    3. 类库实现:Java的标准类库如集合框架、I/O流、网络通信等,其底层实现都可以在OpenJDK源码中找到,这对于理解API的工作方式非常有帮助。 二、JVM解析 1. 类加载器:Java的类加载机制是双亲委派模型,OpenJDK...

    openjdk-analyze:jdk源码分析

    《OpenJDK源码分析——探索Java开发的底层奥秘》 OpenJDK,全称为Open Source Java Development Kit,是Java开发工具集的开源版本,它提供了Java平台标准版(Java SE)的实现。深入理解OpenJDK源码,对于Java开发者...

    openjdk源码2

    OpenJDK源码是理解Java虚拟机(JVM)、类库以及Java语言实现的关键资源,对于开发者来说具有极高的学习价值。下面我们将深入探讨OpenJDK源码中的关键知识点。 1. **HotSpot虚拟机**:OpenJDK的核心部分是HotSpot...

    openjdk hotspot源码

    OpenJDK Hotspot源码是Java开发者深入理解Java虚拟机(JVM)工作原理的关键资源。Hotspot JVM是Oracle公司开发的开源Java虚拟机实现,它以高效的性能优化著称,包括即时编译(JIT)和动态优化。在深入探讨Hotspot...

    OpenJDK中rt.jar源码文件

    3. **源码分析**: 查看rt.jar的源码对于学习Java语言的底层实现非常有帮助。例如,可以研究`Object`类的`clone()`方法是如何工作的,或者`ArrayList`如何实现动态扩容。通过Eclipse等IDE查看源码,可以设置断点,...

    OPENJDK8 源码

    源码分析可以帮助我们深入了解Java虚拟机(JVM)的工作原理、类库的实现细节以及垃圾回收机制等核心内容。 1. **JVM架构与执行引擎** - **字节码解析器**: OpenJDK8使用C1(Client Compiler)和C2(Server ...

    openjdk7u源码

    在Java世界中,源码分析是提升技术能力的重要途径,尤其对于OpenJDK这种基础性软件,其源码更是开发者探索Java运行机制的金钥匙。OpenJDK 7U源码不仅包括了JVM的实现,还涵盖了类库和编译器等多个重要组件,这些组件...

    openjdk7源码

    通过研究OpenJDK7的源码,开发者可以了解Java语言的底层实现,学习如何优化JVM参数,以及如何针对特定场景调整Hotspot的编译和垃圾回收策略。这对于理解Java程序的性能瓶颈,提升软件的运行效率具有极大的帮助。 ...

    openjdk源码3

    《OpenJDK源码探索——深入理解Java运行机制》 OpenJDK,全称为Open Source Java Development Kit,是Java开发工具集的一个开源实现,由Oracle公司主导并维护,旨在为Java开发者提供一个开放、免费的平台来研究和...

    Openjdk9源码

    通过对源码的阅读和分析,开发者可以学习到如何设计和实现一个复杂的软件系统,以及如何遵循开源社区的协作模式。这是一次对Java世界深度探索的宝贵机会,对于任何有志于Java技术研究的人来说都极具价值。

    openJdk 19年4月2号源码

    2019年4月2日的OpenJDK源码版本,包含了HotSpot虚拟机和JDK 12的源代码,对于Java开发者来说,这是一个极其珍贵的学习资源。本文将深入探讨这一关键版本中的主要技术特点和关键组件。 一、HotSpot虚拟机 HotSpot是...

    openjdk-17 GA源码(jdk17-jdk-17-ga.tar.gz)

    理解OpenJDK源码需要扎实的Java基础和一定的底层知识。可以从以下几个步骤入手: 1. 熟悉JVM基本原理:理解类加载、内存模型、垃圾收集等概念。 2. 阅读JDK库源码:了解常用API的实现细节,如Collections、...

    openjdk-18 GA源码(jdk18-jdk-18-ga.zip)

    开发者可以通过分析这些源码,理解Java的内存管理、线程调度、字节码解释和优化等核心机制。例如,`src/hotspot`目录下的源码涉及了虚拟机的实现,包括解析和执行字节码的解释器、即时编译器以及内存管理系统等。 ...

    OpenJDK1.8源码简析V1.0.pptx

    OpenJDK的源码分析可以帮助我们深入理解Java程序的运行机制,包括内存管理、垃圾回收、线程模型、编译与解释器的工作原理等。 1. JVM基本认识 Java虚拟机(JVM)是Java运行时环境的核心,它负责执行Java字节码。...

    openjdk7的langtools源码

    《深入剖析OpenJDK7的LangTools源码》 OpenJDK7是Java开发的一个开源实现,它提供了Java运行环境的基础构建块。LangTools作为OpenJDK7的一部分,扮演着至关重要的角色,它是Java语言工具集的核心,包含了编译器、...

    openjdk1.7 附属源码src.zip

    OpenJDK 1.7源码是Java开发领域的重要参考资料,它揭示了Java平台的核心运行机制,对于开发者来说,理解和研究OpenJDK源码有助于提升编程技能,优化代码性能,以及解决实际问题。src.zip文件包含了OpenJDK 1.7的所有...

Global site tag (gtag.js) - Google Analytics