java之jvm类加载器

  • 2021年10月29日
  • Java

一)JVM类加载器

  • 1)JVM(java虚拟机)启动时,会形成三个层级的加载器加载结构:

    • bootstrap classloader(原始加载器) > extension classloader(扩展类加载器) > system classloader系统(也称为应用)类加载器

  • 2)每个ClassLoader加载class的过程是:

    • 1、检测此Class是否载入过(即在cache中是否有此Class),如果有到8,如果没有则到2

    • 2、如果parent ClassLoader不存在(没有parent 则一定是引导类加载器(bootstrap classLoader)),到4

    • 3、请求parent classloader类加载器载入,如果成功则到8,不成功则到5

    • 4、请求jvm从bootstrap classloader中载入,如果成功则到8

    • 5、寻找Class文件(从与此classloader相关的路径中寻找),如果找不到则到7

    • 6、从文件中载入Class,到8

    • 7、抛出ClassNotFoundException

    • 8、返回Class

/**
 * @项目名称 longlonggo-sample
 * @文件名称 ClassLoadTest.java  版本号:1.0
 * @创建日期 2018年9月27日 
 * @创建作者 me@longlonggo.com
 */
package classload;

import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;

/**
 * 说明: jvm类加载器
 * 
 * @version 1.0
 * @author me@longlonggo.com
 *
 */
public class ClassLoadTest2 {

    public static void main(String[] args) throws IOException {
        /******************************* 【1】系统类加载器 *******************************/
        ClassLoader systemLoader = ClassLoader.getSystemClassLoader();
        // 系统加载器对象:sun.misc.Launcher$AppClassLoader@18b4aac2
        System.out.println("系统加载器:" + systemLoader);
        // 系统加载器加载路径,程序运行的物理路径
        Enumeration<URL> eml = systemLoader.getResources("");
        while (eml.hasMoreElements()) {
            System.out.println("系统加载器路径:" + eml.nextElement());
        }

        
        /******************************* 【2】扩展类加载器 *******************************/
        // 获取 系统类加载器的父加载器,即扩展类加载器对象
        ClassLoader parentLoader = systemLoader.getParent();
        // 扩展类加载器对象:sun.misc.Launcher$ExtClassLoader@5fd0d5ae
        System.out.println("扩展类加载器对象:" + parentLoader);
        System.out.println("扩展类加载器路径:" + System.getProperty("java.ext.dirs"));

        
        /******************************* 【3】引导类加载器 *******************************/
        // 负责加载java的核心类,它实际上不是 java.lang.ClassLoader的子类,而是由JVM自身实现的
        ClassLoader parent2Loader = parentLoader.getParent();
        System.out.println("原始加载器对象:" + parent2Loader);
        URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
        for (int i = 0; i < urls.length; i++) {
            System.out.println("原始加载器核心类库:" + urls[i].toExternalForm());
        }
        
        // 内容输出如下:
        // 系统加载器:sun.misc.Launcher$AppClassLoader@2a139a55
        // 系统加载器路径:file:/C:/workspace/longlonggo-sample/target/classes/
        
        // 扩展类加载器对象:sun.misc.Launcher$ExtClassLoader@5fd0d5ae
        // 扩展类加载器路径:C:Program FilesJavajdk1.8.0_181jrelibext;C:WindowsSunJavalibext
        
        // 原始加载器对象:null
        // 原始加载器核心类库:file:/C:/Program%20Files/Java/jdk1.8.0_181/jre/lib/resources.jar
        // 原始加载器核心类库:file:/C:/Program%20Files/Java/jdk1.8.0_181/jre/lib/rt.jar
        // 原始加载器核心类库:file:/C:/Program%20Files/Java/jdk1.8.0_181/jre/lib/sunrsasign.jar
        // 原始加载器核心类库:file:/C:/Program%20Files/Java/jdk1.8.0_181/jre/lib/jsse.jar
        // 原始加载器核心类库:file:/C:/Program%20Files/Java/jdk1.8.0_181/jre/lib/jce.jar
        // 原始加载器核心类库:file:/C:/Program%20Files/Java/jdk1.8.0_181/jre/lib/charsets.jar
        // 原始加载器核心类库:file:/C:/Program%20Files/Java/jdk1.8.0_181/jre/lib/jfr.jar
        // 原始加载器核心类库:file:/C:/Program%20Files/Java/jdk1.8.0_181/jre/classes
    }
}

注:本文章参考:

http://www.blogjava.net/lhulcn618/archive/2006/05/25/48230.html

http://www.cnblogs.com/jasonstorm/p/5663864.html

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注