Java之类加载
1、class文件结构
2、
魔数:确定这个文件是否为一个能被虚拟机接收的class文件
版本号
常量池:字面量和符号引用。字面量比较接近于 Java 语言层面的的常量概念,如文本字符串、声明为 final 的常量值等。而符号引用则属于编译原理方面的概念。
访问标志:
当前类、父类、接口索引集合
字段表集合:接口或者类中声明的变量 包括类级变量和实例变量
方法表集合:
属性表集合
3、类加载过程
加载-连接-初始化
加载:
- 通过全类名获取定义此类的二进制字节流。
- 将字节流所代表的静态存储结构转换为方法区的运行时数据结构。
- 在内存中生成一个代表该类的
Class
对象,作为方法区这些数据的访问入口。方法区会存储已被虚拟机加载的 类信息、字段信息、方法信息、常量、静态变量、即时编译器编译后的代码缓存等数据。
验证:确保 Class 文件的字节流中包含的信息符合《Java 虚拟机规范》的全部约束要求,保证这些信息被当作代码运行后不会危害虚拟机自身的安全。
准备:正式为类变量分配内存并设置类变量初始值的阶段 这些内存都将在方法区中分配。
赋值为0
赋值为111
解析:虚拟机将常量池内的符号引用替换为直接引用的过程
初始化:
类卸载:该类的 Class 对象被 GC 由 jvm 自带的类加载器加载的类是不会被卸载的。但是由我们自定义的类加载器加载的类是可能被卸载的。
3、类加载器是一个负责加载类的对象。
每个 Java 类都有一个引用指向加载它的 ClassLoader
。
数组类不是通过 ClassLoader
创建的(数组类没有对应的二进制字节流),是由 JVM 直接生成的。
类加载器的主要作用就是加载 Java 类的字节码( .class
文件)到 JVM 中(在内存中生成一个代表该类的 Class
对象)。
4、加载规则——并不会一次性加载所有的类,动态加载,已经加载过的直接返回
5、类加载器:
启动类加载器,最顶层的,通常表示为null 没有父级
扩展类加载器,
应用程序类扩展器:面向用户
自定义类加载器,需要继承 ClassLoader
抽象类 protected Class loadClass(String name, boolean resolve)
:加载指定二进制名称的类,实现了双亲委派机制
protected Class findClass(String name)
:根据类的二进制名称来查找类,默认实现是空方法。
6、双亲委派模型 各种类加载器之间的层次关系被称为类加载器的“双亲委派模型(Parents Delegation Model)”
- 在类加载的时候,系统会首先判断当前类是否被加载过。已经被加载的类会直接返回,否则才会尝试加载(每个父类加载器都会走一遍这个流程)。
- 类加载器在进行类加载的时候,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成(调用父加载器
loadClass()
方法来加载类)。这样的话,所有的请求最终都会传送到顶层的启动类加载器BootstrapClassLoader
中。 - 只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载(调用自己的
findClass()
方法来加载类)。 - 如果子类加载器也无法加载这个类,那么它会抛出一个
ClassNotFoundException
异常
JVM 判定两个 Java 类是否相同的具体规则:JVM 不仅要看类的全名是否相同,还要看加载此类的类加载器是否一样。只有两者都相同的情况,才认为两个类是相同的。即使两个类来源于同一个 Class
文件,被同一个虚拟机加载,只要加载它们的类加载器不同,那这两个类就必定不相同。
双亲委派模型保证了 Java 程序的稳定运行,可以避免类的重复加载
打破双亲委派机制的方法:重写loadclass()方法
原文地址:https://blog.csdn.net/qq_49802050/article/details/140619381
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!