剖析JVM类加载器

localClass类加载过程的步骤

加载->验证->准备->解析->初始化->使用->卸载

加载:在硬盘上查找并通过IO读入字节码文件,使用到类时才会加载,也就是说会把new出的对象存放到内存

验证:验证字节码文件的格式是否正确

准备:给类的静态变量分配内存,并赋予默认值

解析:将符号引用替换为直接引用

初始化:对类的静态变量进行初始化为指定的值,执行静态代码块

类加载器

引导类加载器:负责加载支撑JVM运行的位于JRE的lib目录下的核心类库,也就是JDK自身携带的类,比如rt.jar

扩展类加载器:负责加载支撑JVM运行的位于JRE的lib目录下的ext扩展目录中的JAR类包

应用程序类加载器(父加载器是扩展类加载器):负责加载ClassPath路径下的类包,主要就是加载的是自己写的那些类

自定义加载器:负责加载用户自定义路径下的类包

引导类加载器打印出来为null呢?

System.out.println(String.class.getClassLoader())

因为引导类加载器生成的对象是C++生成的,所以Java打印出来是null

类加载器的初始化过程

首先会创建JVM启动器实例:sum.misc.Launcher。sum.misc.Launcher初始化使用了单例模式设计,保证一个JVM虚拟机内只有一个sum.misc.Launcher实例。在sum.misc.Launcher构造方法内部,创建了两个类加载器,分别是扩展类加载器sum.misc.Launcher.ExtClassLoader和应用类加载器sum.misc.Launcher.AppClassLoader。JVM默认使用Launcher的getClassLoader()方法返回类加载器AppClassLoader的实例加载我们的应用程序

双亲委派机制

JVM的双亲委派机制是这这样的。要加载类会先从应用程序类加载器中查看是否这个类已经在应用类上加载过了,如果没有加载好,它会先往上去扩展类加载器上查看,如果还没加载好,那么它会往引导类加载器上去加载;如果引导类加载器上没有这个类,无法加载到的话,它就会让子加载器自己加载

其实简单一点说就是:先找父亲加载,不行再由儿子自己加载

为什么是从应用类加载器开始加载而不是从引导类加载器?

首先从代码层面考虑,JVM提供的代码就是先从应用类加载器最先开始加载,其次我们写的代码类基本上95%以上都是在应用类加载器上面的;第一次确实要多走一些步骤,但是走过一圈加载之后,就可以直接在应用程序类加载器上面找到

为什么要设计双亲委派机制?

沙箱安全机制:自己写的java.lang.String.class类不会被加载,这样可以防止核心API库被随意篡改

避免类的重复加载:当父加载器已经加载了该类时,子类就不会再加载了,保证被加载类的唯一性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

—熙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值