看完这篇JVM类加载器,再也不怕阿里面试官了!
0 前言
全是干货的技术殿堂
文章收录在我的 GitHub 仓库,欢迎Star/fork:https://github.com/Wasabi1234/Java-Interview-Tutorial
类加载器是如何定位具体的类文件并读取的呢?
在类加载器家族中存在着类似人类社会的权力等级制度
- 最高层的
Bootstrap
在JVM启动时创建的,通常由与操作系统相关的本地代码实现,是最根基的类加载器,负责装载最核心的Java类,比如Object、System、 String ,Java运行时的rt.jar等jar包 - JDK9的
Platform ClassLoader
负责加载<JAVA_HOME>\lib\ext目录中的,或者java.ext.dirs系统变量指定的路径中的所以类库;
加载一些扩展的系统类,比如XML、加密、压缩相关的功能类等;
JDK9之前是Extension ClassLoader
. - 第三层
Application ClassLoader
应用类加载器,主要是加载用户定义的CLASSPATH
路径下的类
第二、三层类加载器为Java语言实现,用户也可以自定义类加载器
查看本地类加载器的方式如下:
在JDK8环境中,执行结果如下
AppClassLoader的Parent为Bootstrap,它是通过C/C++实现的,并不存在于JVM体系内,所以输出为 null
低层次的当前类加载器,不能覆盖更高层次类加载器已经加载的类
如果低层次的类加载器想加载一个未知类,要非常礼貌地向上逐级询问:“请问,这个类已经加载了吗?”
被询问的高层次类加载器会自问两个问题
- 我是否已加载过此类
- 如果没有,是否可以加载此类
只有当所有高层次类加载器在两个问题的答案均为“否”时,才可以让当前类加载器加载这个未知类
左侧绿色箭头向上逐级询问是否已加载此类,直至
Bootstrap ClassLoader,然后向下逐级尝试是否能够加载此类,如果都加载不了,则通知发起加载请求的当前类加载器,准予加载
在右侧的三个小标签里,列举了此层类加载器主要加载的代表性类库,事实上不止于此
通过如下代码可以查看Bootstrap 所有已加载类库
执行结果
Bootstrap加载的路径可以追加,不建议修改或删除原有加载路径
在JVM中增加如下启动参数,则能通过
Class.forName正常读取到指定类,说明此参数可以增加Bootstrap的类加载路径:
-Xbootclasspath/a:/Users/sss/book/ easyCoding/byJdk11/src
如果想在启动时观察加载了哪个jar包中的哪个类,可以增加
-XX:+TraceClassLoading
此参数在解决类冲突时非常实用,毕竟不同的JVM环境对于加载类的顺序并非是一致的
有时想观察特定类的加载上下文,由于加载的类数量众多,调试时很难捕捉到指定类的加载过程,这时可以使用条件断点功能
比如,想查看HashMap的加载过程,在loadClass处打个断点,并且在condition框内输入如图
JVM如何确立每个类在JVM的唯一性
类的全限定名和加载这个类的类加载器的ID
在学习了类加载器的实现机制后,知道双亲委派模型并非强制模型,用户可以自定义类加载器,在什么情况下需要自定义类加载器呢?
- 隔离加载类
在某些框架内进行中间件与应用的模块隔离,把类加载到不同的环境
比如,阿里内某容器框架通过自定义类加载器确保应用中依赖的jar包不会影响到中间件运行时使用的jar包 - 修改类加载方式
类的加载模型并非强制,除Bootstrap外,其他的加载并非一定要引入,或者根据实际情况在某个时间点进行按需进行动态加载 - 扩展加载源
比如从数据库、网络,甚至是电视机机顶盒进行加载 - 防止源码泄露
Java代码容易被编译和篡改,可以进行编译加密。那么类加载器也需要自定义,还原加密的字节码。
实现自定义类加载器的步骤
- 继承ClassLoader
- 重写findClass()方法
- 调用defineClass()方法
一个简单的类加载器实现的示例代码如下
由于中间件一般都有自己的依赖jar包,在同一个工程内引用多个框架时,往往被迫进行类的仲裁
按某种规则jar包的版本被统一指定, 导致某些类存在包路径、类名相同的情况,就会引起类冲突,导致应用程序出现异常
主流的容器类框架都会自定义类加载器,实现不同中间件之间的类隔离,有效避免了类冲突。
- 点赞
- 收藏
- 分享
- 文章举报
- 看完这篇JVM,阿里面试官都不怕!看完就能拿offer
- java类加载机制,再也不怕面试官的刁难
- 图解Java线程的生命周期,看完再也不怕面试官问了
- 图解Java线程的生命周期,看完再也不怕面试官问了
- JVM类加载器过程
- jvm类加载-全盘负责和双亲委派机制
- 面试问烂的 MySQL 四种隔离级别,看完吊打面试官!
- 阿里面试官的分享Java面试中需要准备哪些多线程并发的技术要点
- JVM类加载过程
- Jvm类加载机制详解---类加载器及双亲委托模型
- JVM类加载机制
- 七、JVM类加载机制
- JVM类加载机制简介
- 面试阿里露馅被怼了!面试官:这简历一看就是包装过的
- JVM类加载机制
- 《Java虚拟机原理图解》 JVM类加载器机制与类加载过程
- JVM类生命周期概述:加载时机与加载过程
- JVM类加载机制入门总结
- jvm类加载过程
- JVM类加载机制