IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 深入理解类加载 -> 正文阅读

[Java知识库]深入理解类加载

一:类文件到虚拟机

💡:类加载就是将字节码文件加载到内存,并生成数据访问入口的机制,
类加载的最终目的是生成数据访问入口。

图示:
在这里插入图片描述
那么字节码文件是如何加载进内存的呢?这就要涉及类加载机制。


二: 类加载过程

所谓类加载本质上就是把Class文件加载进内存,并对数据进行校验,解析,初始化,最终生成Java虚拟机能够之间使用的数据,即java.lang.Class对象。

在这里插入图片描述

2.1:装载

装载:

  1. 通过一个类的全限定名获取一个类的二进制字节流。
  2. 将这个二进制字节流所代表的静态储存结构转化为方法区运行时数据结构。
  3. 在内存中生成代表这个类的java.lang.Class对象,作为方法区中这个类的各种数据的访问入口。

注意:JVM官方并为指定从class文件中获取一个类的二进制字节流,也就是说并为指定从哪里获取二进制字节流,这给开发者提供了开发的环境,我们一般有以下几种方式获取一个类的二进制字节流。

  • 从本地系统中直接加载
    典型场景:这个我就不废话了
  • 通过网络下载.class文件
    典型场景:Web Applet,也就是我们的小程序应用
  • 从zip,jar等归档文件中加载.class文件
    典型场景:后续演变为jar、war格式
  • 从专有数据库中提取.class文件
    典型场景:JSP应用从专有数据库中提取.class文件,较为少见
  • 将Java源文件动态编译为.class文件,也就是运行时计算而成
    典型场景:动态代理技术
  • 从加密文件中获取, 典型场景:典型的防Class文件被反编译的保护措施

2.2 验证

验证主要是为了确保Class文件中的字节流包含的信息完全符合当前虚拟机的要求,并且还要求我们的信息不会危害虚拟机自身的安全,导致虚拟机的崩溃。

而验证过程主要分为以下四种验证

2.2.1 文件格式验证

验证字节流是否符合Class文件格式的规范,并且能被当前版本的虚拟机处理,该验证的主要目的是保证输入的字节流能正确地解析并存储于方法区之内。这阶段的验证是基于二进制字节流进行的,只有经过该阶段的验证后,字节流才会进入内存的方法区中进行存储,后面验证都是基于方法区的存储结构进行的。

2.2.2 元数据验证

对类的元数据信息进行语义校验(其实就是对Java语法校验),保证不存在不符合Java语法规范的元数据信息。

2.2.3 字节码验证

进行数据流和控制流分析,确定程序语义是合法的、符合逻辑的。对类的方法体进行校验分析,保证被校验的类的方法在运行时不会做出危害虚拟机安全的行为。获取类的二进制字节流的阶段是我们JAVA程序员最关注的阶段,也是操控性最强的一个阶段。因为这个阶段我们可以对于我们的类加载器进行操作,比如我们想自定义类加载器进行操作用以完成加载又或者我们想通过JAVA Agent来完成我们的字节码增强操作。

2.2.4 符号引用验证

这是最后一个阶段的验证,它发生在虚拟机将符号引用转化为直接引用的时候(解析阶段),可以看作是对类自身以外的信息(常量池中的各种符号引用)进行匹配性的校验。符号引用验证的目的是确保解析动作能正常执行。


2.3 准备

  1. 为类变量赋初值,这里的初值是类型的默认值,即零值。
    注意:这里会为基础数据类型赋对应的初值,而引用数据类型为空值。
  2. final static 修饰的变量在编译的阶段就已经赋值了,在准备阶段会显示初始化。
  3. 准备阶段不会为实例变量赋值,实例变量会随类一起被加载到堆区去。

2.4 解析

我们只需要知道在解析阶段注意发生的事就是将符号引用转换为直接引用。

解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。
解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用限定符7类符号引用进行。


2.5 初始化

初始化阶段主要是执行类构造器()方法的过程。

在准备阶段类变量已经赋值过零值,在该阶段主要是按照程序员设置的计划为类变量赋值。
说的通俗些该过程是执行< clinit >()方法的过程,这个方法不需要我们程序员编写,会由编译器在编译的时候自动收集类变量的直接初始化和静态代码块中初始化的信息生成的类构造方法。
在这里我们可以看出来以下信息 1.静态代码块就是在初始化阶段执行的 2.给类变量初始化要么直接在定义的时候赋值,要么通过静态代码块赋值。

类初始化的步骤:
1. 如果这个类还没有被加载链接,则先执行加载链接操作
2. 如果这个类的直接父类还没有初始化,则先初始化这个类的直接父类。
3. 假如类中有初始化语句则依次执行这些初始化语句。


2.6 使用

并不是JVM启动就会将所有类初始化,在启动时只会讲JVM运行所需要的基础类库加载并初始化,其它的类都需要在主动引用时再初始化。

只有类的主动引用会引起类的初始化,类的主动引用有以下6种情况:

  • 创建类的实例,也就是new的方式
  • 访问某个类或接口的静态变量,或者对该静态变量赋值
  • 调用类的静态方法
  • 反射(如 Class.forName(“com.carl.Test”)
  • 初始化某个类的子类,则其父类也会被初始化
  • Java虚拟机启动时被标明为启动类的类(JvmCaseApplication ),直接接使用 java.exe 命令来运行某个主类

2.7 卸载

类的卸载需要满足以下三种情况:

  • 该类所有的实例都已经被回收,也就是java堆中不存在该类的任何实例。
  • 加载该类的ClassLoader已经被回收
  • 该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法。

如果以上三个条件全部满足,jvm就会在方法区垃圾回收的时候对类进行卸载,类的卸载过程其实就是在方法区中清空类信息,java类的整个生命周期就结束了。但是一般情况下启动类加载器加载的类不会被卸载,而我们的其他两种基础类型的类加载器只有在极少数情况下才会被卸载。

从上面可以看出来类一般加载到JVM运行时数据区中的方法区后就不会被回收,直到JVM虚拟机实例销毁时进行类卸载,除了极少数的情况下类才会被卸载。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-05-02 13:25:12  更:2022-05-02 13:25:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:08:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码