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()方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值