JVM学习笔记(2)-类加载子系统

一.内存结构简述

内存结构简图:

在这里插入图片描述

运行简述:

首先是把class文件加载到内存中(使用的是类加载子系统),
然后生成大的class的对象,将必要的静态属性的进行初始化(是在方法区这块进行的)
本地方法栈主要是在调用本地的类库是使用的比如调用本地C的类库

详细图:

英文版:

在这里插入图片描述

中文版:

在这里插入图片描述

通过类加载子系统解析class文件,获取类的信息,常量,变量信息,方法的指令等,使之有组织的分配到内存之中
执行引擎需要逐条的去解释指令

二.类加载器与类的加载过程

简述:

类加载器子系统作用:

在这里插入图片描述

类加载器ClassLoader角色:

在这里插入图片描述

类的加载过程:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


加载过程详情:

加载:

在这里插入图片描述

补充: 加载.class文件的方式

在这里插入图片描述

链接:

在这里插入图片描述

初始化:

在这里插入图片描述

示例1:

在这里插入图片描述

进行反编译之后

在这里插入图片描述

示例2:

在这里插入图片描述在这里插入图片描述

示例3:

一个类只会被加载一次

在这里插入图片描述
在这里插入图片描述

三.类加载器分类

在这里插入图片描述
在这里插入图片描述

public class ClassLoaderTest {
    public static void main(String[] args) {

        // 获取系统类加载器
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);// sun.misc.Launcher$AppClassLoader@18b4aac2

        // 获取上层: 扩展类加载器
        ClassLoader extClassLoader = systemClassLoader.getParent();
        System.out.println(extClassLoader);// sun.misc.Launcher$ExtClassLoader@1540e19d

        // 获取其上层: 获取不到引导类加载器
        ClassLoader bootstrapClassLoader = extClassLoader.getParent();
        System.out.println(bootstrapClassLoader);// null

        // 对于用户自定义来说: 默认使用系统类加载器进行加载
        ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
        System.out.println(classLoader);// sun.misc.Launcher$AppClassLoader@18b4aac2

        // String类使用引导类加载器加载类加载的 ---> Java的核心类库都是使用引导类加载器进行加载的
        ClassLoader classLoader1 = String.class.getClassLoader();
        System.out.println(classLoader1);// null
    }
}

虚拟机自带的加载器:

引导类加载器: Bootstrap ClassLoader

在这里插入图片描述

扩展类加载器: Extension ClassLoader

在这里插入图片描述

应用程序类加载器(系统类加载器) : AppClassLoader

在这里插入图片描述

public class ClassLoaderTest1 {
    public static void main(String[] args) {
        System.out.println("========启动类加载器========");
        // 获取BootstrapClassLoader能够加载的api的路径
        URL[] urLs = Launcher.getBootstrapClassPath().getURLs();
        for (URL element : urLs) {
            System.out.println(element.toExternalForm());
        }
//        file:/C:/Program%20Files/Java/jdk1.8.0_131/jre/lib/resources.jar
//        file:/C:/Program%20Files/Java/jdk1.8.0_131/jre/lib/rt.jar
//        file:/C:/Program%20Files/Java/jdk1.8.0_131/jre/lib/sunrsasign.jar
//        file:/C:/Program%20Files/Java/jdk1.8.0_131/jre/lib/jsse.jar
//        file:/C:/Program%20Files/Java/jdk1.8.0_131/jre/lib/jce.jar
//        file:/C:/Program%20Files/Java/jdk1.8.0_131/jre/lib/charsets.jar
//        file:/C:/Program%20Files/Java/jdk1.8.0_131/jre/lib/jfr.jar
//        file:/C:/Program%20Files/Java/jdk1.8.0_131/jre/classes

        // 从上面的路径中随意选择一个类,来看看他的类加载器是什么: 引导类加载器
        ClassLoader classLoader = Provider.class.getClassLoader();
        System.out.println(classLoader);// null


        System.out.println("========扩展类加载器========");
        String extDirs = System.getProperty("java.ext.dirs");
        for (String path : extDirs.split(";")) {
            System.out.println(path);
        }
//        C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext
//        C:\Windows\Sun\Java\lib\ext

        // 从上面的路径中随意选择一个类,来看看他的类加载器是什么:
        ClassLoader classLoader2 = CurveDB.class.getClassLoader();
        System.out.println(classLoader2);// sun.misc.Launcher$ExtClassLoader@29453f44
    }
}
用户自定义类加载器:

在这里插入图片描述
在这里插入图片描述

示例
public class CustomClassLoader extends ClassLoader{

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        try {
            byte[] result = getClassFromCustompath(name);
            if (result == null) {
                throw new FileNotFoundException();
            }else {
                return defineClass(name, result, 0, result.length);
            }
        }catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        throw new ClassNotFoundException();
    }

    private byte[] getClassFromCustompath(String name) {
        // 从自定义路径中加载指定类
        // 如果指定路径的字节码文件进行了加密,则需要在此方法中进行解密操作
        // .....
        return null;
    }

    public static void main(String[] args) {
        CustomClassLoader customClassLoader = new CustomClassLoader();
        try {
            Class<?> clazz = Class.forName("One", true, customClassLoader);
            Object obj = clazz.newInstance();
            System.out.println(obj.getClass().getClassLoader());
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

关于ClassLoader

在这里插入图片描述

继承关系:

在这里插入图片描述

获取ClassLoader的途径

在这里插入图片描述

四.双亲委派机制

在这里插入图片描述

工作原理:

在这里插入图片描述

例子1:

在这里插入图片描述

例子2:

在这里插入图片描述

JDBC的接口是由核心类加载器进行加载的, 而在JDBC.jar中的实现类是由当前线程上下文类加载器(系统内加载器)进行加载的

优势:

在这里插入图片描述

沙箱安全机制

在这里插入图片描述

五.其他

在这里插入图片描述

对类加载器的引用

在这里插入图片描述

类的主动使用和被动使用

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值