《深入理解JVM》7-类加载

从Class文件到类的过程要经过

  1. 加载-
  2. 链接-
  3. 初始化

三个过程。根据上一节讲到的内容,java语言中分为基本类型和引用类型

基本类型是虚拟机预先定义好的,引用类型分为数组-类-接口。数组也是虚拟机直接生成的,只有类和接口对应的是字节流(操作码流)

操作码可以是class文件形式,也可以是网络上读取,也可以是机器内部生成。我们以常见的class文件为例。

加载

查找类文件,并读取字节码到内存

双亲委派机制

jvm提供了默认的三个类加载器

  1. 启动类加载器(boot strap classLoader),最顶级,是C++代码实现,所以获取不到,null代替。加载jre路径下 lib目录下的类
  2. 扩展类加载器(extension class loader),启动类加载器的子类,加载 jre下lib/ext目录下的类
  3. 应用类加载器 (application class loader),扩展类加载器的子类,加载应用相关的jar包等。

比如有这样一个需求,需要加载com.david.study.test.Demo.class文件。首先获取当前线程的类加载器A,然后逐级向上查找父加载器,看父加载器能否加载到Demo文件,如果可以,给内存中的Demo类取唯一符号:类加载器+类全路径名。如果父加载器加载不到类,就自己取查找文件。

注意:如果一个类被不同的加载器加载,jvm会认为两个类不是同一个类。用户也可以自定义类加载器

链接

  1. 验证:验证class字节码是否符合虚拟机标准(版本号,magic no等)

  2. 准备:准备给类的静态变量分配存储空间,构建实现虚方法动态绑定的方法表。还有调用本类的方法和属性,并不知道具体的地址,所以只能保存为目标类的名称+方法+参数+返回值这样组成的符号引用,

  3. 解析:把字节码当中的符号引用解析为实际地址,比如调用B对象的update方法,之前只知道update的符号地址,现在要解析为jvm中B类update的实际地址。

初始化

类中的静态字段或静态代码段,在初始化阶段给予赋值及执行,这些被集中放置在<clinit>方法中。java虚拟机在执行<clinit>方法时会加锁,保证只执行一次。

调用初始化的时机:

  1. 程序启动时,初始化主类
  2. new 命令
  3. 访问静态方法或静态属性
  4. 子类初始化会出发父类初始化
  5. 使用Api反射
  6. MethodHandle实例执行时

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值