JVM--类加载

34 篇文章 0 订阅
6 篇文章 0 订阅

步骤

加载-连接-初始化

其中连接又分为验证-准备-解析三步

 

加载类

  1. 接收:通过全限定名获取二进制数据流,即通过文件系统读入一个class后缀的文件或解析jar、zip包归档文件得到class文件。还有一些奇葩方法例如将二进制数据放入db通过db读取,或者通过http接收。
  2. 解析:解析类的二进制数据流为方法区内的数据结构
  3. 创建:创建Class类实例

 

 

类加载器ClassLoader

分类

  1. BootStrap ClassLoader启动类加载器,由C实现并且在java中没有对象与之对应。用于加载系统核心类,如rt.jar中的java类。特例:java.lang.String类属于系统核心类,因此会被BootStrap 加载器加载,故无法通过getClassLoader 获取对象的累加载器。
  2. Extension ClassLoader 扩展类加载器,用于加载环境变量%JAVA_HOME%/lib/ext/*.jar包中的java类。
  3. App ClassLoader 应用/系统类加载器,用于加载用户类。
  4. 自定义ClassLoader,用于加载一些特殊用途的用户类。

 

 

ClassLoader的双亲委派

 

classLoader会先判断类是否被加载过,如果加载过直接返回,如果没有,会先判断其双亲是否存在,存在则调用双亲的loadClass加载类。不存在,判断使用bootstrap classloader加载,然后还不存在,使用当前classloader加载类。

 

双亲委派拓展

 

rt.jar中有些功能,提供了接口,但是需要应用自行实现,例如JDBC驱动。称之为SPI。那么问题是rt.jar是由bootstrap加载器加载的,判断类是否被加载是从自定义加载器到bootstrap类加载器的,所以bootstrap中也无法调用低级别类加载器获取实例,所以这时候需要一个上下文类加载器。在当前线程下存在两个方法,一个set方法,设置当前使用的ClassLoader,一个get,获取上下文ClassLoader。放SPI需要使用应用类加载器加载的类时,则可以通过当前线程传入的AppClassLoader加载外部实现。

 

打破双亲委派

 

通过自定义ClassLoader并且重写loadClass方法实现。不过要注意当自定义加载器加微类时,被加载类的默认父类Object有可能无法加载到。因为自定义ClassLoader可能指向的地址不存在Object类信息。还需要使用其他类加载器进行加载。调用其super.loadClass进行Object类的加载。

 

热替换

 

java首先是不能像其他需要那样替换了源文件即可实现功能替换的。因为java中虚拟机通过classLoader 将class文件通过二进制流加载到了虚拟机中。

所以只替换class文件是没用的。

那么要做到热更新或者说热替换,就要从classloader入手,通过classloader加载新的源文件。

这里有个重点是:不同的类加载器加载同一个Class文件,在JVM中也不会认为他们是一个类。会分开处理。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值