leader:学的不错,给你涨薪!JVM的类加载机制你是否理解到我这个程度?

1.2 链接阶段

========

验证

验证类是否符合 JVM规范,安全性检查,阻止不合法的类继续运行。用 UE 等支持二进制的编辑器修改 HelloWorld.class的魔数,在控制台运行:

大厂码农涨薪10k的秘诀:JVM的类加载机制你是否理解到这个程度?

准备

为 static 变量分配空间,设置默认值:

  • static 变量在 JDK 7 之前存储于 instanceKlass 末尾,从 JDK 7 开始,存储于 _java_mirror 末尾

  • static 变量分配空间和赋值是两个步骤,分配空间在准备阶段完成,赋值在初始化阶段完成

  • 如果 static 变量是 final 的基本类型,以及字符串常量,那么编译阶段值就确定了,赋值在准备阶段完成

  • 如果 static 变量是 final 的,但属于引用类型,那么赋值也会在初始化阶段完成

  • 将常量池中的符号引用解析为直接引用

解析

将常量池中的符号引用解析为直接引用:

大厂码农涨薪10k的秘诀:JVM的类加载机制你是否理解到这个程度?

1.3 初始化阶段

=========

< init()> V 方法

初始化即调用 < cinit>()V ,虚拟机会保证这个类的『构造方法』的线程安全。

发生的时机

概括地说,类初始化是【懒惰的】

  • main 方法所在的类,总会被首先初始化

  • 首次访问这个类的静态变量或静态方法时

  • 子类初始化,如果父类还没初始化,会引发

  • 子类访问父类的静态变量,只会触发父类的初始化

  • Class.forName

  • new 会导致初始化

不会导致类初始化的情况:

  • 访问类的 static final 静态常量(基本类型和字符串)不会触发初始化

  • 类对象.class 不会触发初始化

  • 创建该类的数组不会触发初始化

  • 类加载器的 loadClass 方法

测试代码:

大厂码农涨薪10k的秘诀:JVM的类加载机制你是否理解到这个程度?

验证(测试时请先全部注释,每次只执行其中一个)

大厂码农涨薪10k的秘诀:JVM的类加载机制你是否理解到这个程度?

大厂码农涨薪10k的秘诀:JVM的类加载机制你是否理解到这个程度?

1.4 练习

======

从字节码分析,使用 a,b,c 这三个常量是否会导致 E 初始化:

大厂码农涨薪10k的秘诀:JVM的类加载机制你是否理解到这个程度?

典型应用 - 完成懒惰初始化单例模式:

大厂码农涨薪10k的秘诀:JVM的类加载机制你是否理解到这个程度?

以上的实现特点是:

  • 懒惰实例化

  • 初始化时的线程安全是有保障的

2. 类加载器

========

以 JDK 8 为例:

大厂码农涨薪10k的秘诀:JVM的类加载机制你是否理解到这个程度?

类加载器的优先级(由高到低):启动类加载器 -> 扩展类加载器 -> 应用程序类加载器 -> 自定义类加载器

2.1 启动类加载器

==========

用 Bootstrap 类加载器加载类:

大厂码农涨薪10k的秘诀:JVM的类加载机制你是否理解到这个程度?

执行:

大厂码农涨薪10k的秘诀:JVM的类加载机制你是否理解到这个程度?

输出:

大厂码农涨薪10k的秘诀:JVM的类加载机制你是否理解到这个程度?

-Xbootclasspath 表示设置 bootclasspath

其中 /a:. 表示将当前目录追加至 bootclasspath 之后

可以有以下几个方式替换启动类路径下的核心类:

  • java -Xbootclasspath: < new bootclasspath>

  • 前追加:java -Xbootclasspath/a:<追加路径>

  • 后追加:java -Xbootclasspath/p:<追加路径>

大厂码农涨薪10k的秘诀:JVM的类加载机制你是否理解到这个程度?

2.2 扩展类加载器

==========

大厂码农涨薪10k的秘诀:JVM的类加载机制你是否理解到这个程度?

程序执行:

大厂码农涨薪10k的秘诀:JVM的类加载机制你是否理解到这个程度?

输出结果:

大厂码农涨薪10k的秘诀:JVM的类加载机制你是否理解到这个程度?

写一个同名的类:

大厂码农涨薪10k的秘诀:JVM的类加载机制你是否理解到这个程度?

打个 jar 包:

大厂码农涨薪10k的秘诀:JVM的类加载机制你是否理解到这个程度?

将 jar 包拷贝到JAVA_HOME/jre/lib/ext(扩展类加载器加载的类必须是以jar包方式存在),重新执行 Load5_2

输出:

大厂码农涨薪10k的秘诀:JVM的类加载机制你是否理解到这个程度?

2.3 双亲委派模式

==========

所谓的双亲委派,就是指调用类加载器的 loadClass 方法时,查找类的规则。

注意:这里的双亲,翻译为上级似乎更为合适,因为它们并没有继承关系

大厂码农涨薪10k的秘诀:JVM的类加载机制你是否理解到这个程度?

大厂码农涨薪10k的秘诀:JVM的类加载机制你是否理解到这个程度?

例如:

大厂码农涨薪10k的秘诀:JVM的类加载机制你是否理解到这个程度?

执行流程为:

最后

由于篇幅原因,就不多做展示了

7f997d7212.png)

执行流程为:

最后

[外链图片转存中…(img-UvuhdtgP-1714412430053)]

[外链图片转存中…(img-H3vZuWtH-1714412430054)]

[外链图片转存中…(img-Zk5Pb9KR-1714412430054)]

[外链图片转存中…(img-X8GkxbWF-1714412430054)]

[外链图片转存中…(img-pgoLGHtV-1714412430055)]

[外链图片转存中…(img-ph4C1dZp-1714412430056)]

由于篇幅原因,就不多做展示了

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值