Java 核心技术面试精讲
杨晓峰
前 Oracle 首席工程师
125942 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 44 讲
Java 核心技术面试精讲
15
15
1.0x
00:00/00:00
登录|注册

第23讲 | 请介绍类加载过程,什么是双亲委派模型?

将常量池中的符号引用替换为直接引用
创建静态变量并初始化初始值
核验字节信息符合Java虚拟机规范
包括静态字段赋值和静态初始化块逻辑
执行类初始化的代码逻辑
解析
准备
验证
可自定义类加载器实现自己的加载过程
映射为JVM认可的数据结构(Class对象)
从不同数据源读取字节码数据
解决方法
遇到过类似情况
AppCDS
AOT
用于进程内隔离、从不同数据源获取类定义信息、操纵字节码
类加载器结构和机制变化
原生模块化支持
避免重复加载Java类型
当类加载器加载类型时,尽量代理给父加载器去做
初始化阶段
链接阶段
加载阶段
Jar Hell问题
优化类加载速度
自定义类加载器
Java 9变化
双亲委派模型
类加载过程
类加载过程和双亲委派模型

该思维导图由 AI 生成,仅供参考

Java 通过引入字节码和 JVM 机制,提供了强大的跨平台能力,理解 Java 的类加载机制是深入 Java 开发的必要条件,也是个面试考察热点。
今天我要问你的问题是,请介绍类加载过程,什么是双亲委派模型?

典型回答

一般来说,我们把 Java 的类加载过程分为三个主要步骤:加载、链接、初始化,具体行为在Java 虚拟机规范里有非常详细的定义。
首先是加载阶段(Loading),它是 Java 将字节码数据从不同的数据源读取到 JVM 中,并映射为 JVM 认可的数据结构(Class 对象),这里的数据源可能是各种各样的形态,如 jar 文件、class 文件,甚至是网络数据源等;如果输入数据不是 ClassFile 的结构,则会抛出 ClassFormatError。
加载阶段是用户参与的阶段,我们可以自定义类加载器,去实现自己的类加载过程。
第二阶段是链接(Linking),这是核心的步骤,简单说是把原始的类定义信息平滑地转化入 JVM 运行的过程中。这里可进一步细分为三个步骤:
验证(Verification),这是虚拟机安全的重要保障,JVM 需要核验字节信息是符合 Java 虚拟机规范的,否则就被认为是 VerifyError,这样就防止了恶意信息或者不合规的信息危害 JVM 的运行,验证阶段有可能触发更多 class 的加载。
准备(Preparation),创建类或接口中的静态变量,并初始化静态变量的初始值。但这里的“初始化”和下面的显式初始化阶段是有区别的,侧重点在于分配所需要的内存空间,不会去执行更进一步的 JVM 指令。
解析(Resolution),在这一步会将常量池中的符号引用(symbolic reference)替换为直接引用。在Java 虚拟机规范中,详细介绍了类、接口、方法和字段等各个方面的解析。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Java类加载机制是Java开发中必要的基础知识,也是面试热点。本文介绍了类加载的三个主要步骤:加载、链接、初始化,以及双亲委派模型。通过讲解加载阶段将字节码数据映射为JVM认可的数据结构,链接阶段包括验证、准备和解析,初始化阶段执行类初始化的代码逻辑,以及双亲委派模型的工作原理。此外,还提到了Java 8以前各种类加载器的结构和Java 9中Jigsaw项目对类加载器结构和机制的变化。文章还介绍了自定义类加载器的常见场景和类加载速度优化的方法,如AOT和AppCDS。总的来说,本文内容涵盖了类加载机制的基础知识和扩展问题,适合想深入了解Java类加载机制的读者阅读。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Java 核心技术面试精讲》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(41)

  • 最新
  • 精选
  • 无崖子Z
    Jar hell jar包冲突,对于大项目或没有maven的项目是比较麻烦的。1 应用无法启动 2 编译时没问题,运行时报错。解决方法:1 改为maven 项目,使包的管理和依赖可视化2 在1的基础上,解决明显的包编译冲突 3 根据运行时报错找到冲突的包,或者要排除的包

    作者回复: 不错

    2018-06-29
    44
  • Allen
    还能再讲讲ORM映射的细节吗?端个小板凳准备听😁

    作者回复: 有计划提到,但暂时没计划单独讲,如果需要的朋友多,也许后期加餐吧

    2018-06-28
    23
  • hu
    您好,面试时,被问到:双亲委托加载的缺点。可以讲解一下么?谢谢

    作者回复: 这个问题似乎比较费解,与其说缺点,不如说什么常见不适合双亲委派,例如,我们希望一个jvm能够同时加载某类的不同版本,那么双亲委派就不合适了,需要的是在不同范围内(例如模块)单独加载

    2018-10-10
    2
    19
  • hankchan
    看到评论说应该叫单亲的,真是挺奇怪的..... 好像...parent的中文翻译是父母吧?父母是不是双亲?所以就算翻译错将parent写成了parents,中文翻译成双亲,也没问题吧?

    作者回复: 语言功底很赞

    2019-01-25
    3
    14
  • A_吖我去
    老师老师,如果我写了一个java.lang.String类,怎么进行加载的,怎么跟原来的类进行区分的?

    作者回复: 试验下吧,除非你修改jdk本身实现,不然加载不了

    2018-07-03
    6
  • 浪尖
    我们一般可以使用下面方法获取父加载器,但是在通常的 JDK/JRE 实现中,扩展类加载器 getParent() 都只能返回 null。 不应该是扩展类加载器,而是启动类加载器的父类加载器为null

    作者回复: 这个行为是为了防止应用代码获取bootstrap cl哦 。当然 bootstrap也没有parent

    2018-09-12
    5
  • 落霞与孤鹜
    两个war依赖相同的jar包,部署在同一个tomcat,类会重复加载吗?

    作者回复: 没有深入研究Tomcat类加载,逻辑上,这种不应该是可选吗?要么共享,要么各自一份,各有利弊的样子

    2018-07-05
    2
    4
  • 二狗子
    也有人叫父类委托机制的

    作者回复: 嗯呢

    2019-01-15
    2
    2
  • Winston
    jdk现在的更新模式变了,jdk9是不稳定版本,还需要研究吗?是不是只学习LTS的版本就好了

    作者回复: 这些版本是连续的,不会浪费,lts确实是未来升级的待选,可以作为重点

    2018-08-19
    2
  • 落霞与孤鹜
    那两个war依赖相同的jar包,运行在同一个jvm,类会重复加载吗?

    作者回复: 回复过了,我认为应该看具体server设计,一般共享jar或者单独应该都能做得到

    2018-07-07
    1
收起评论
显示
设置
留言
41
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部