JVM 类加载器
发布日期:2021-06-28 18:55:03
浏览次数:2
分类:技术文章
本文共 1614 字,大约阅读时间需要 5 分钟。
一、字节码与运行时程序的关系:
写好的代码经过编译变成了字节码,并且可以打包成Jar文件。 然后就可以让JVM去加载需要的字节码,变成持久代/元数据区上的Class对象,接着才会执行我们的程序逻辑。
二、类的生命周期和加载过程
一个类的生命周期包括以下几个方面:
- 加载
- 验证
- 准备
- 解析
- 初始化
- 使用
- 卸载
在这些过程中,1-5步骤被称作类加载。
三、类加载时机
提到类加载时机,有个细节需要记录的是:类会在哪些情况下被初始化?这里记录下一些情况。
初始化何时会被触发:
- 当虚拟机启动时,初始化用户指定的主类,就是启动执行的 main方法所在的类;
- 当遇到用以新建目标类实例的new指令时,初始化new指令的目标类,就是new一个类的时候要初始化。
- 当遇到调用静态方法的指令时,初始化该静态方法所在的类
- 当遇到访问静态字段的指令时,初始化该静态字段所在的类
- 子类的初始化会触发父类的初始化
- 如果一个接口定义了 default 方法,那么直接实现或者间接实现该接口的类的初始化,会触发该接口的初始化;
- 使用反射API对某个类进行反射调用时,初始化这个类,其实跟前面一样,反射调用要么是已经有实例了,要么是静态方法,都需要初始化
- 当初次调用MethodHandle实例时,初始化该MethodHandle指向的方法所在的类。
同时以下几种情况不会执行类初始化:
- 通过子类引用父类的静态字段,只会触发父类的初始化,而不会触发子类的初始化。
- 定义对象数组,不会触发该类的初始化
- 常量在编译期间会存入调用类的常量池中,本质上并没有直接引用定义常量的类,不会触发定义常量所在的类。
- 通过类名获取Class对象,不会触发类的初始化,Hello.class不会让Hello类初始化
- 通过Class.forName加载指定类时,如果指定参数initialize为false时,也不会触发类初始化,其实这个参数是告诉虚拟机,是否要对类进行初始化。Class.forName(“jvm.Hello”)默认会加载Hello类。
- 通过ClassLoader默认的loadClass方法,也不会触发初始化动作(加载了,但是不初始化)
四、类加机制
类加载器有以下几个:
- 启动类加载器(BootstrapClassLoader)
- 扩展类加载器(ExtClassLoader)
- 应用类加载器(AppClassLoader)
其中扩展类加载器(ExtClassLoader)和 应用类加载器(AppClassLoader)都是继承RLClassLoader类。
这里有一个小细节就是,String类是由哪个加载器加载的。答案是:java.lang.String是由启动类加载器加载的,所以String.class.getClassLoader()就会返回null。
类加载机制有三个特点:
- 双亲委托:当一个自定义类加载器需要加载一个类,比如java.lang.String,它很懒,不会一上来就直接试图加载它,而是先委托自己的父加载器去加载,父加载器如果发现自己还有父加载器,会一直往前找,这样只要上级加载器,比如启动类加载器已经加载了某个类比如java.lang.String,所有的子加载器都不需要自己加载了。如果几个类加载器都没有加载到指定名称的类,那么会抛出ClassNotFountException异常。
- 负责依赖:如果一个加载器在加载某个类的时候,发现这个类依赖于另外几个类或接口,也会去尝试加载这些依赖项。
- 缓存加载:为了提升加载效率,消除重复加载,一旦某个类被一个类加载器加载,那么它会缓存这个加载结果,不会重复加载。
五、总结:
- 介绍了类加载的机制,以及类的生命周期。
- 接着我们介绍了,在那种情况下会初始化类,哪些情况下不会。
- 介绍了类加载器,这部分是老生常谈的东西。不过有一个小细节需要留心就是:String是谁加载的。
- 介绍了类加载特点。
转载地址:https://blog.csdn.net/xt00002003/article/details/114682061 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
做的很好,不错不错
[***.243.131.199]2024年04月08日 01时33分19秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
[golang]-go中字符串格式化与fmt包简介
2019-04-28
[Leet-go]-复杂链表的复制
2019-04-28
五分钟上手ECharts图形报表
2019-04-28
权限控制之Spirng Security框架
2019-04-28
android课程表!大厂offer手到擒来,满满干货指导
2019-04-29
android网!2021中级Android开发面试解答,进阶学习资料!
2019-04-29
android自动化测试工具!为什么有人说Android开发不再吃香?建议收藏
2019-04-29
android系统架构五层!最详细的解释小白也能听懂,2年以上经验必看
2019-04-29
android线刷包!跟我一起手写EventBus吧,大厂内部资料
2019-04-29
android实战!百度、阿里、滴滴、新浪的面试心经总结,满满干货指导
2019-04-29
Android小技巧:一线互联网移动架构师NDK模块开发!含BATJM大厂
2019-04-29
docker搭建postgresql9.4主从同步复制集群
2019-04-29
docker下postgis12+postgis3.0搭建
2019-04-29
什么是函数式编程
2019-04-29
Java开发必用的工具包
2019-04-29
世界500强公司要求员工必须熟练掌握的七种工作方法
2019-04-29
九个做事的顺序,你会更加优秀
2019-04-29
史上最详细的Hadoop环境搭建
2019-04-29
最近经历的一些大数据(Spark/Hadoop)面试题
2019-04-29