zoukankan      html  css  js  c++  java
  • JVM

    1 java是如何调用main函数的

    我们知道JVM是由C/C++语言实现的,那么JVM跟CLASS打交道则需要JNI(Java Native Interface)JNI 使得Java虚拟机中的Java程序可以调用本地应用/或库,也可以被其他程序调用这座桥梁,当我们在命令行执行java时,由C/C++实现的java应用通过JNI找到了HelloWorld里面符合规范的main方法,然后开始调用。我们来看下java命令的源码就知道了

    /*
    * Get the application's main class.
    */
    if (jarfile != 0) {
    mainClassName = GetMainClassName(env, jarfile);
    ... ...
    mainClass = LoadClass(env, classname);
    if(mainClass == NULL) { /* exception occured */
    ... ...
    /* Get the application's main method */
    mainID = (*env)->GetStaticMethodID(env, mainClass, "main", "([Ljava/lang/String;)V");
    ... ...
    {/* Make sure the main method is public */
    jint mods;
    jmethodID mid;
    jobject obj = (*env)->ToReflectedMethod(env, mainClass, mainID, JNI_TRUE);
    ... ...
    /* Build argument array */
    mainArgs = NewPlatformStringArray(env, argv, argc);
    if (mainArgs == NULL) {
    ReportExceptionDescription(env);
    goto leave;
    }
    /* Invoke main method. */
    (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
    

      

    2 类加载器

    上一节我们留了一个核心的环节,就是JVM在执行类的入口之前,首先得找到类再然后再把类装到JVM实例里面,也即是JVM进程维护的内存区域内。我们当然知道是一个叫做类加载器的工具把类加载到JVM实例里面,抛开细节从操作系统层面观察,那么就是JVM实例在运行过程中通过IO从硬盘或者网络读取CLASS二进制文件,然后在JVM管辖的内存区域存放对应的文件。我们目前还不知道类加载器的实现,但是我们从功能上判断无非就是读取文件(从硬盘或网络)到内存,这个是很普通也很简单的操作。

    如从操作系统层面看的话,如果只是加载,以上代码就足以把类文件加载到JVM内存里面了。但是结果就是乱糟糟的把一堆毫无秩序的类文件往内存里面扔,没有良好的管理也没法用,所以需要我们需要设计一套规则来管理存放内存里面的CLASS文件,我们称为类加载的设计模式或者类加载机制,这个下文会重点解释。

    系统 or 自定义 名称 作用 类加载器 类加载路径 实现原理
    系统默认加载器  

    Bootstrap class loader

    启动类加载器,加载JDK核心类 C/C++实现

     /jre/lib

    URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
    /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/resources.jar
    ...
    /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/rt.jar

    本地方C++实现

    Extensions class loader

    扩展类加载器,加载JAVA扩展类库 JAVA实现

    /jre/lib/ext

    System.out.println(System.getProperty("java.ext.dirs"));
    /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/ext:

    扩展类加载器ExtClassLoader本质上也是URLClassLoader

    System class loader 系统类加载器,加载应用指定环境变量路径下的类 sun.misc.Launcher$AppClassLoader -classpath下面的所有类 系统类加载器AppClassLoader本质上也是URLClassLoader
    自定义类加载器 自定义 内置类加载器只加载了最少需要的核心JAVA基础类和环境变量下的类,但是我们应用往往需要依赖第三方中间件来完成额外的业务,那么如何把它们的类加载进来就显得格外重要了。幸好JVM提供了自定义类加载器,可以很方便的完成自定义操作,最终目的也是把外部的类文件加载到JVM内存 自定义 把外部的类文件加载到JVM内存 通过继承ClassLoader类并且复写findClass和loadClass方法就可以达到自定义获取CLASS文件的目的
  • 相关阅读:
    使用递归输出某个目录下所有子目录和文件
    如何进行复杂度分析?
    什么是时间复杂度?什么是空间复杂度?
    什么是复杂度?为什么要进行复杂度分析?
    什么是递归?递归的优缺点是什么?
    Executor 如何使用?
    什么是spring boot?为什么要用?
    spring boot核心配置文件是什么?
    @Autowired的作用是什么?
    @RequestMapping的作用是什么?
  • 原文地址:https://www.cnblogs.com/wxdlut/p/11011326.html
Copyright © 2011-2022 走看看