当前位置: 首页 > news >正文

JVM_类的加载、链接、初始化、卸载、主动使用、被动使用

①. 说说类加载分几步?

  • ①. 按照Java虚拟机规范,从class文件到加载到内存中的类,到类卸载出内存为止,它的整个生命周期包括如下7个阶段:

  1. 第一过程的加载(loading)也称为装载
  2. 验证、准备、解析3个部分统称为链接(Linking)
  3. 在Java中数据类型分为基本数据类型和引用数据类型。基本数据类型由虚拟机预先定义,引用数据类型则需要进行类的加载

②. 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过类的加载、类的链接、类的初始化这三个步骤来对类进行初始化。如果不出现意外,JVM将会连续完成这三个步骤,所以有时也把这三个步骤统称为类加载或者初始化

③. 从程序中类的使用过程看:

    ②. 过程一:类的加载(Loading)

    • ①. 类的加载指的是将类的.class文件中的二进制数据读取到内存中,存放在运行时数据区的方法区中,并创建一个大的Java.lang.Class对象,用来封装方法区内的数据结构 在加载类时,Java虚拟机必须完成以下3件事情:

    ②. 对于①的说明,我们也可以这样去理解:所谓装载(加载),简而言之就是将Java类的字节码文件加载到机器内存中,并在内存中构建出Java类的原型——类模板对象

    (所谓类模板对象,其实就是Java类在JVM内存中的一个快照,JVM将从字节码文件中解析出的常量池、类字段、类方法等信息存储到类模板中,这样JVM在运行期便能通过类模板而获取Java类中的任意信息,能够对Java类的成员变量进行遍历,也能进行Java方法的调用)

    ③. 对于类的二进制数据流,虚拟机可以通过多种途径产生或获得(只要所读取的字节码符合JVM规范即可)

    1.虚拟机可能通过文件系统读入一个class后缀的文件(最常见)

    2.读入jar、zip等归档数据包,提取类文件。

    3.事先存放在数据库中的类的二进制数据

    4.使用类似于HTTP之类的协议通过网络进行加载

    5.在运行时生成一段Class的二进制信息等

    ④. Class实例的位置

    (类将.class文件加载至元空间后,会在堆中创建一个Java.lang.Class对象,用来封装类位于方法区内的数据结构,该Class对象是在加载类的过程中创建的,每个类都对应有一个Class类型的对象)

    1. 通过类的全名,获取类的二进制数据流
    2. 解析类的二进制数据流为方法区内的数据结构(Java类模型)
    3. 创建java.lang.Class类的实例,表示该类型。作为方法区这个类的各种数据的访问入口

    ③. 过程二:链接(Linking)

    • ①. 验证:确保Class文件的字节流中包含信息符合当前虚拟机要求,保证被加载类的正确性

      1.  

      1.目的是确保Class文件的字节流中包含信息符合当前虚拟机要求,保证被加载类的正确性,不会危害虚拟机自身安全
      2.主要包括四种验证:文件格式验证,元数据验证,字节码验证,符号引用验证
      3.格式检查:是否以魔术oxCAFEBABE开头,主版本和副版本是否在当前Java虚拟机的支持范围内,数据中每一项是否都拥有正确的长度等

        ②. 准备(静态变量,不能是常量)

          1.为类变量分配内存并且设置该类变量的默认初始化值
          2.这里不包含用final修饰的static,因为final在编译的时候就会分配了,准备阶段会显式赋值
          3.这里不会为实例变量分配初始化,类变量会分配在方法区中,而实例变量会随着对象一起分配到Java堆中
          4.注意:Java并不支持boolean类型,对于boolean类型,内部实现是int,由于int的默认值是0,故对应的,boolean的默认值就是false

            public class ClassInitTest {private  static int num=1; //类变量的赋值动作//静态代码快中的语句static{num=2;number=20;System.out.println(num);//System.out.println(number); 报错:非法的前向引用}//Linking之prepare: number=0 -->initial:20-->10private static int number=10;public static void main(String[] args) {System.out.println(ClassInitTest.num);System.out.println(ClassInitTest.number);}
            }
            

          • ③. 若该类具有父类,Jvm会保证子类的< clinit >() 执行前,父类的< clinit >() 已经执行完成。clinit 不同于类的构造方法(init) (由父及子,静态先行)

           

          public class ClinitTest1 {static class Father{public static int A=1;static{A=2;}}static class Son extends Father{public static int B=A;}public static void main(String[] args) {//这个输出2,则说明父类已经全部加载完毕System.out.println(Son.B);}
          }
          

           

          /*** @author TANGZHI* @create 2021-01-01 18:49* 哪些场景下,java编译器就不会生成<clinit>()方法*/
          public class InitializationTest1 {//场景1:对应非静态的字段,不管是否进行了显式赋值,都不会生成<clinit>()方法public int num = 1;//场景2:静态的字段,没有显式的赋值,不会生成<clinit>()方法public static int num1;//场景3:比如对于声明为static final的基本数据类型的字段,不管是否进行了显式赋值,都不会生成<clinit>()方法public static final int num2 = 1;
          }
          

           

          
          /*** @author TANGZHI* @create 2021-01-01 ** 说明:使用static + final修饰的字段的显式赋值的操作,到底是在哪个阶段进行的赋值?* 情况1:在链接阶段的准备环节赋值* 情况2:在初始化阶段<clinit>()中赋值* 结论:* 在链接阶段的准备环节赋值的情况:* 1. 对于基本数据类型的字段来说,如果使用static final修饰,则显式赋值(直接赋值常量,而非调用方法)通常是在链接阶段的准备环节进行* 2. 对于String来说,如果使用字面量的方式赋值,使用static final修饰的话,则显式赋值通常是在链接阶段的准备环节进行** 在初始化阶段<clinit>()中赋值的情况:* 排除上述的在准备环节赋值的情况之外的情况。* 最终结论:使用static + final修饰,且显示赋值中不涉及到方法或构造器调用的基本数据类型或String类型的显式赋值,是在链接阶段的准备环节进行。*/
          public class InitializationTest2 {public static int a = 1;//在初始化阶段<clinit>()中赋值public static final int INT_CONSTANT = 10;//在链接阶段的准备环节赋值public static final Integer INTEGER_CONSTANT1 = Integer.valueOf(100);//在初始化阶段<clinit>()中赋值public static Integer INTEGER_CONSTANT2 = Integer.valueOf(1000);//在初始化阶段<clinit>()中赋值public static final String s0 = "helloworld0";//在链接阶段的准备环节赋值public static final String s1 = new String("helloworld1");//在初始化阶段<clinit>()中赋值public static String s2 = "helloworld2";public static final int NUM1 = new Random().nextInt(10);//在初始化阶段<clinit>()中赋值
          }
          

           

          package com.xiaozhi;/*** @author TANGZHI* @create 2021-05-25*/
          class StaticA {static {try {Thread.sleep(1000);} catch (InterruptedException e) {}try {Class.forName("com.xiaozhi.StaticB");} catch (ClassNotFoundException e) {e.printStackTrace();}System.out.println("StaticA init OK");}
          }class StaticB {static {try {Thread.sleep(1000);} catch (InterruptedException e) {}try {Class.forName("com.xiaozhi.StaticA");} catch (ClassNotFoundException e) {e.printStackTrace();}System.out.println("StaticB init OK");}
          }public class StaticDeadLockMain extends Thread {private char flag;public StaticDeadLockMain(char flag) {this.flag = flag;this.setName("Thread" + flag);}@Overridepublic void run() {try {Class.forName("com.xiaozhi.Static" + flag);} catch (ClassNotFoundException e) {e.printStackTrace();}System.out.println(getName() + " over");}public static void main(String[] args) throws InterruptedException {StaticDeadLockMain loadA = new StaticDeadLockMain('A');loadA.start();StaticDeadLockMain loadB = new StaticDeadLockMain('B');loadB.start();}
          }
          

          ⑤. 主动引用(触发在初始化阶段的Clinit方法)

             

            # 注意,如果把A接口中的默认方法注释,那么就只输出:子类初始化......
            输出:
            CompareB的初始化
            子类初始化.....
            public class DemoB implements A{
                static{
                    System.out.println("子类初始化......");
                }
                public static void main(String[] args) {

                }
            }
            interface A{
                public static final Thread t = new Thread() {
                    {
                        System.out.println("CompareB的初始化");
                    }
                };
                default void method1(){
                    System.out.println("====");
                }
            }
             

            ⑥. 被动使用

            ⑦. 过程四:类的Using(使用)

            ⑧. 过程五:类的Unloading(卸载)

                      相关文章:

                      JVM_类的加载、链接、初始化、卸载、主动使用、被动使用

                      ①. 说说类加载分几步&#xff1f; ①. 按照Java虚拟机规范,从class文件到加载到内存中的类,到类卸载出内存为止,它的整个生命周期包括如下7个阶段: 第一过程的加载(loading)也称为装载验证、准备、解析3个部分统称为链接(Linking)在Java中数据类型分为基本数据类型和引用数据…...

                      2025最新版MySQL安装使用指南

                      2025最新版MySQL安装使用指南 The Installation and Usage Guide of the Latest Version of Oracle MySQL in 2025 By JacksonML 1. 获取MySQL 打开Chrome浏览器&#xff0c;访问官网链接&#xff1a;https://www.mysql.com/ &#xff0c;随即打开MySQL官网主页面&#xff…...

                      MIMIC IV数据库中mimiciv_hosp的transfers表的careunit分析

                      以下是MIMIC IV数据库中mimiciv_hosp的transfers表的careunit的所有值&#xff0c;从医学专业角度分析&#xff0c;下面哪些科室会有实施心脏或神经手术&#xff1f; Cardiac Surgery Cardiac Vascular Intensive Care Unit (CVICU) Cardiology Cardiology Surgery Intermediat…...

                      AI学习指南HuggingFace篇-Hugging Face 的环境搭建

                      一、引言 Hugging Face作为自然语言处理(NLP)领域的强大工具,提供了丰富的预训练模型和数据集,极大地简化了开发流程。本文将详细介绍如何搭建适合Hugging Face开发的环境,包括Python环境配置、依赖安装以及推荐的开发工具,帮助读者准备好开发环境。 二、Python环境配置…...

                      白嫖DeepSeek:一分钟完成本地部署AI

                      1. 必备软件 LM-Studio 大模型客户端DeepSeek-R1 模型文件 LM-Studio 是一个支持众多流行模型的AI客户端&#xff0c;DeepSeek是最新流行的堪比GPT-o1的开源AI大模型。 2. 下载软件和模型文件 2.1 下载LM-Studio 官方网址&#xff1a;https://lmstudio.ai 打开官网&#x…...

                      C# dataGridView1获取选中行的名字

                      在视觉项目中编写的框架需要能够选择产品或复制产品等方便后续换型&#xff0c;视觉调试仅需调试相机图像、调试视觉相关参数、标定&#xff0c;再试跑调试优化参数。 C# dataGridView1 鼠标点击某一行能够计算出是那一行 使用CellMouseClick事件 首先&#xff0c;在Form的构造…...

                      Day28(补)-【AI思考】-AI会不会考虑自己的需求?

                      文章目录 AI会不会考虑自己的需求&#xff1f;一、**技术本质&#xff1a;深度≠理解**二、**传播机制&#xff1a;热搜如何制造幻觉**三、**伦理考量&#xff1a;为何必须"撇清"**关键结论 AI会不会考虑自己的需求&#xff1f; 让思想碎片重焕生机的灵魂&#xff1a…...

                      幸运数字——蓝桥杯

                      1.问题描述 哈沙德数是指在某个固定的进位制当中&#xff0c;可以被各位数字之和整除的正整数。例如 126126 是十进制下的一个哈沙德数&#xff0c;因为 (126)10mod(126)0&#xff1b;126 也是八进制下的哈沙德数&#xff0c;因为 (126)10(176)8&#xff0c;(126)10​mod(176)…...

                      快速提升网站收录:避免常见SEO误区

                      本文转自&#xff1a;百万收录网 原文链接&#xff1a;https://www.baiwanshoulu.com/26.html 在快速提升网站收录的过程中&#xff0c;避免常见的SEO误区是至关重要的。以下是一些常见的SEO误区及相应的避免策略&#xff1a; 一、关键词堆砌误区 误区描述&#xff1a; 很多…...

                      [Java]泛型(二)泛型方法

                      1.定义 在 Java 中&#xff0c;泛型方法是指在方法声明中使用泛型类型参数的一种方法。它使得方法能够处理不同类型的对象&#xff0c;而不需要为每种类型写多个方法&#xff0c;从而提高代码的重用性。 泛型方法与泛型类不同&#xff0c;泛型方法的类型参数仅仅存在于方法的…...

                      如何监控ubuntu系统某个程序的运行状态,如果程序出现异常,对其自动重启。

                      在Ubuntu系统中&#xff0c;可以通过编写脚本结合cron或systemd来监控程序的运行状态&#xff0c;并在程序异常时自动重启。以下是具体步骤&#xff1a; 方法一&#xff1a;使用Shell脚本和Cron 编写监控脚本 创建一个Shell脚本来检查程序是否运行&#xff0c;并在程序异常时重…...

                      UE学习日志#15 C++笔记#1 基础复习

                      1.C20的import 看看梦开始的地方&#xff1a; import <iostream>;int main() {std::cout << "Hello World!\n"; } 经过不仔细观察发现梦开始的好像不太一样&#xff0c;这个import是C20的模块特性 如果是在VS里编写的话&#xff0c;要用这个功能需要新…...

                      CSS:跑马灯

                      <div class"swiper-container"><div class"swiper-wrapper"><!-- 第一组 --><div class"item" v-for"item in cardList" :key"first-item.id"><img :src"item.image" alt""…...

                      rust 自定义错误(十二)

                      错误定义&#xff1a; let file_content parse_file("test.txt");if let Err(e) file_content {println!("Error: {:?}", e);}let file_content parse_file2("test.txt");if let Err(e) file_content {match e {ParseFileError::File > …...

                      EWM 变更库存类型

                      目录 1 简介 2 配置 3 业务操作 1 简介 一般情况下 EWM 标准收货流程是 ROD&#xff08;Ready on Dock&#xff09; --> AFS&#xff08;Avaiable for Sale&#xff09;&#xff0c;对应 AG 001 --> AG 002&#xff0c;对应库存类型 F1 --> F2。 因业务需要反向进…...

                      AI大模型开发原理篇-9:GPT模型的概念和基本结构

                      基本概念 生成式预训练模型 GPT&#xff08;Generative Pre-trained Transformer&#xff09;模型 是由 OpenAI 开发的基于 Transformer 架构的自然语言处理&#xff08;NLP&#xff09;模型&#xff0c;专门用于文本生成任务。它的设计理念在于通过大规模的预训练来学习语言模…...

                      MySQL数据库(二)

                      一 DDL (一 数据库操作 1 查询-数据库&#xff08;所有/当前&#xff09; 1 所有数据库&#xff1a; show databases; 2 查询当前数据库&#xff1a; select database(); 2 创建-数据库 可以定义数据库的编码方式 create database if not exists ax1; create database ax2…...

                      从0到1:C++ 开启游戏开发奇幻之旅(二)

                      目录 游戏开发核心组件设计 游戏循环 游戏对象管理 碰撞检测 人工智能&#xff08;AI&#xff09; 与物理引擎 人工智能 物理引擎 性能优化技巧 内存管理优化 多线程处理 实战案例&#xff1a;开发一个简单的 2D 射击游戏 项目结构设计 代码实现 总结与展望 游戏…...

                      【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.18 逻辑运算引擎:数组条件判断的智能法则

                      1.18 逻辑运算引擎&#xff1a;数组条件判断的智能法则 1.18.1 目录 #mermaid-svg-QAFjJvNdJ5P4IVbV {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-QAFjJvNdJ5P4IVbV .error-icon{fill:#552222;}#mermaid-svg-QAF…...

                      EasyExcel写入和读取多个sheet

                      最近在工作中&#xff0c;作者频频接触到Excel处理&#xff0c;因此也对EasyExcel进行了一定的研究和学习&#xff0c;也曾困扰过如何处理多个sheet&#xff0c;因此此处分享给大家&#xff0c;希望能有所帮助 目录 1.依赖 2. Excel类 3.处理Excel读取和写入多个sheet 4. 执…...

                      LLM架构与优化:从理论到实践的关键技术

                      标题&#xff1a;“LLM架构与优化&#xff1a;从理论到实践的关键技术” 文章信息摘要&#xff1a; 文章探讨了大型语言模型&#xff08;LLM&#xff09;开发与应用中的关键技术&#xff0c;包括Transformer架构、注意力机制、采样技术、Tokenization等基础理论&#xff0c;以…...

                      【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.22 形状操控者:转置与轴交换的奥秘

                      1.22 形状操控者&#xff1a;转置与轴交换的奥秘 目录 #mermaid-svg-Qb3eoIWrPbPGRVAf {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Qb3eoIWrPbPGRVAf .error-icon{fill:#552222;}#mermaid-svg-Qb3eoIWrPbPGRVAf…...

                      NLP模型大对比:Transformer >Seq2Seq > LSTM > RNN > n-gram

                      结论 Transformer 大于 传统的Seq2Seq 大于 LSTM 大于 RNN 大于 传统的n-gram n-gram VS Transformer 我们可以用一个 图书馆查询 的类比来解释它们的差异&#xff1a; 一、核心差异对比 维度n-gram 模型Transformer工作方式固定窗口的"近视观察员"全局关联的&q…...

                      DeepSeek部署教程(基于Ollama)

                      虽说在过年&#xff0c;但不能忘了学习。这几天科技圈最火的莫过于deepseek&#xff0c;我抽空也学习一下deepseek的部署过程&#xff0c;主要还是因为官方服务已经彻底瘫了[手动狗头]。 1、下载Ollama并安装 https://github.com/ollama/ollama/releases/latest/download/Oll…...

                      Java基础面试题总结(题目来源JavaGuide)

                      问题1&#xff1a;Java 中有哪 8 种基本数据类型&#xff1f;它们的默认值和占用的空间大小知道不&#xff1f; 说说这 8 种基本数据类型对 应的包装类型。 在 Java 中&#xff0c;有 8 种基本数据类型&#xff08;Primitive Types&#xff09;&#xff1a; 基本数据类型关键…...

                      WPS mathtype间距太大、显示不全、公式一键改格式/大小

                      1、间距太大 用mathtype后行距变大的原因 mathtype行距变大到底怎么解决-MathType中文网 段落设置固定值 2、显示不全 设置格式&#xff1a; 打开MathType编辑器点击菜单栏中的"格式(Format)"选择"间距(Spacing)"在弹出的对话框中调整"分数间距(F…...

                      宇宙大爆炸是什么意思

                      根据宇宙大爆炸学说&#xff0c;宇宙间的一切都在彼此远离&#xff0c;而且距离越远&#xff0c;远离的速度越快。我们只能在地球上观察这种现象&#xff0c;而我们观察到的速度符合如下公式&#xff0c;其中 为哈勃常数&#xff0c; 为距离&#xff0c; 为速度&#xff08;…...

                      MotionLCM 部署笔记

                      目录 依赖项 humanml3d&#xff1a; sentence-t5-large 下载数据&#xff1a; 报错&#xff1a;No module named sentence_transformers 继续报错&#xff1a;from transformers.integrations import CodeCarbonCallback 解决方法&#xff1a; GitHub - Dai-Wenxun/Moti…...

                      VLLM性能调优

                      1. 抢占 显存不够的时候&#xff0c;某些request会被抢占。其KV cache被清除&#xff0c;腾退给其他request&#xff0c;下次调度到它&#xff0c;重新计算KV cache。 报这条消息&#xff0c;说明已被抢占&#xff1a; WARNING 05-09 00:49:33 scheduler.py:1057 Sequence gr…...

                      ESP32-S3模组上跑通esp32-camera(39)

                      接前一篇文章:ESP32-S3模组上跑通esp32-camera(38) 一、OV5640初始化 2. 相机初始化及图像传感器配置 上一回继续对reset函数的后一段代码进行解析。为了便于理解和回顾,再次贴出reset函数源码,在components\esp32-camera\sensors\ov5640.c中,如下: static int reset…...