JVM 虚拟机 执行 class 字节码七个阶段:加载、验证、准备、解析、初始化、使用、卸载。

机器学习分类算法之XGBoost(集成学习算法) 目录 走进XGBoost 什么是XGBoost? XGBoost树的定义 XGBoost核心算法 正则项:树的复杂程度 XGBoost与GBDT有什么不同 XGBoost需要注意的点 XGBoost重要参数详解 调参步骤及思想 XGBoost代码案例 相关性分析 n_estimators(学习曲线) max_depth(学习曲线) 调整max_depth 和min_child_weight 调整gamma 调整subsample 和colsample_bytree 调整正则 阅读详情

一、加载

 

下面是对于加载过程最为官方的描述。

加载阶段是类加载过程的第一个阶段。在这个阶段,JVM 的主要目的是将字节码从各个位置(网络、磁盘等)转化为二进制字节流加载到内存中,接着会为这个类在 JVM 的方法区创建一个对应的 Class 对象,这个 Class 对象就是这个类各种数据的访问入口。

其实加载阶段用一句话来说就是:把代码数据加载到内存中。这个过程对于我们解答这道问题没有直接的关系,但这是类加载机制的一个过程,所以必须要提一下。

二、验证

当 JVM 加载完 Class 字节码文件并在方法区创建对应的 Class 对象之后,JVM 便会启动对该字节码流的校验,只有符合 JVM 字节码规范的文件才能被 JVM 正确执行。这个校验过程大致可以分为下面几个类型:

1.JVM规范校验。JVM 会对字节流进行文件格式校验,判断其是否符合 JVM 规范,是否能被当前版本的虚拟机处理。

例如:文件是否是以 0x cafe bene开头,主次版本号是否在当前虚拟机处理范围之内等。

2.代码逻辑校验。JVM 会对代码组成的数据流和控制流进行校验,确保 JVM 运行该字节码文件后不会出现致命错误。

例如一个方法要求传入 int 类型的参数,但是使用它的时候却传入了一个 String 类型的参数。一个方法要求返回 String 类型的结果,但是最后却没有返回结果。

代码中引用了一个名为 Apple 的类,但是你实际上却没有定义 Apple 类。

当代码数据被加载到内存中后,虚拟机就会对代码数据进行校验,看看这份代码是不是真的按照JVM规范去写的。这个过程对于我们解答问题也没有直接的关系,但是了解类加载机制必须要知道有这个过程。

 

三、准备(重点)

当完成字节码文件的校验之后,JVM 便会开始为类变量分配内存并初始化。这里需要注意两个关键点,即内存分配的对象以及初始化的类型。

1.内存分配的对象。Java 中的变量有「类变量」和「类成员变量」两种类型,「类变量」指的是被 static 修饰的变量,而其他所有类型的变量都属于「类成员变量」。

在准备阶段,JVM 只会为「类变量」分配内存,而不会为「类成员变量」分配内存。「类成员变量」的内存分配需要等到初始化阶段才开始。

例如下面的代码在准备阶段,只会为 factor 属性分配内存,而不会为 website 属性分配内存。

public static int factor = 3;
public String website = "www.cnblogs.com/chanshuyi";

2.初始化的类型。在准备阶段,JVM 会为类变量分配内存,并为其初始化。

但是这里的初始化指的是为变量赋予 Java 语言中该数据类型的零值,而不是用户代码里初始化的值。

例如下面的代码在准备阶段之后,sector 的值将是 0,而不是 3。

public static int sector = 3;

但如果一个变量是常量(被 static final 修饰)的话,那么在准备阶段,属性便会被赋予用户希望的值。例如下面的代码在准备阶段之后,number 的值将是 3,而不是 0

public static final int number = 3;

之所以 static final 会直接被复制,而 static 变量会被赋予零值。其实我们稍微思考一下就能想明白了。

两个语句的区别是一个有 final 关键字修饰,另外一个没有。而 final 关键字在 Java 中代表不可改变的意思,意思就是说 number 的值一旦赋值就不会在改变了。

既然一旦赋值就不会再改变,那么就必须一开始就给其赋予用户想要的值,因此被 final 修饰的类变量在准备阶段就会被赋予想要的值。

而没有被 final 修饰的类变量,其可能在初始化阶段或者运行阶段发生变化,所以就没有必要在准备阶段对它赋予用户想要的值。

四、解析

当通过准备阶段之后,JVM 针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符 7 类引用进行解析。

这个阶段的主要任务是将其在常量池中的符号引用替换成直接其在内存中的直接引用。

其实这个阶段对于我们来说也是几乎透明的,了解一下就好。

五、初始化(重点)

到了初始化阶段,用户定义的 Java 程序代码才真正开始执行。在这个阶段,JVM 会根据语句执行顺序对类对象进行初始化,一般来说当 JVM 遇到下面 5 种情况的时候会触发初始化:

1.遇到 new、getstatic、putstatic、invokestatic 这四条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。

生成这4条指令的最常见的Java代码场景是:使用new关键字实例化对象的时候、读取或设置一个类的静态字段(被final修饰、已在编译器把结果放入常量池的静态字段除外)的时候,以及调用一个类的静态方法的时候。

2.使用 java.lang.reflect 包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。

3.当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。

4.当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。

5.当使用 JDK1.7 动态语言支持时,如果一个 java.lang.invoke.MethodHandle实例最后的解析结果 REF_getstatic,REF_putstatic,REF_invokeStatic 的方法句柄,并且这个方法句柄所对应的类没有进行初始化,则需要先出触发其初始化。

看到上面几个条件你可能会晕了,但是不要紧,不需要背,知道一下就好,后面用到的时候回到找一下就可以了。

六、使用

当 JVM 完成初始化阶段之后,JVM 便开始从入口方法开始执行用户的程序代码。这个阶段也只是了解一下就可以。

七、卸载

当用户程序代码执行完毕后,JVM 便开始销毁创建的 Class 对象,最后负责运行的 JVM 也退出内存。这个阶段也只是了解一下就可以。

看完了Java的类加载机智之后,是不是有点懵呢。不怕,我们先通过一个小例子来醒醒神。

public class Book {
    public static void main(String[] args)
    {
        System.out.println("Hello ShuYi.");
    }

    Book()
    {
        System.out.println("书的构造方法");
        System.out.println("price=" + price +",amount=" + amount);
    }

    {
        System.out.println("书的普通代码块");
    }

    int price = 110;

    static
    {
        System.out.println("书的静态代码块");
    }

    static int amount = 112;
}

思考一下上面这段代码输出什么?

书的静态代码块
Hello ShuYi.

下面我们来简单分析一下,首先根据上面说到的触发初始化的5种情况的第4种(当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类),我们会进行类的初始化。

那么类的初始化顺序到底是怎么样的呢?

重点来了!

在我们代码中,我们只知道有一个构造方法,但实际上Java代码编译成字节码之后,是没有构造方法的概念的,只有类初始化方法 和 对象初始化方法 。

那么这两个方法是怎么来的呢?

       类初始化方法。编译器会按照其出现顺序,收集类变量的赋值语句、静态代码块,最终组成类初始化方法。类初始化方法一般在类初始化的时候执行。

上面的这个例子,其类初始化方法就是下面这段代码了:

static
    {
        System.out.println("书的静态代码块");
    }
    static int amount = 112;

       对象初始化方法。编译器会按照其出现顺序,收集成员变量的赋值语句、普通代码块,最后收集构造函数的代码,最终组成对象初始化方法。对象初始化方法一般在实例化类对象的时候执行。

上面这个例子,其对象初始化方法就是下面这段代码了:

{
        System.out.println("书的普通代码块");
    }
    int price = 110;
    System.out.println("书的构造方法");
    System.out.println("price=" + price +",amount=" + amount);

类初始化方法 和 对象初始化方法 之后,我们再来看这个例子,我们就不难得出上面的答案了。

但细心的朋友一定会发现,其实上面的这个例子其实没有执行对象初始化方法。

因为我们确实没有进行 Book 类对象的实例化。如果你在 main 方法中增加 new Book() 语句,你会发现对象的初始化方法执行了!

感兴趣的朋友可以自己动手试一下,我这里就不执行了。

通过了上面的理论和简单例子,我们下面进入更加复杂的实战分析吧!

                                                                      实战分析

class Grandpa
{
    static
    {
        System.out.println("爷爷在静态代码块");
    }
}
class Father extends Grandpa
{
    static
    {
        System.out.println("爸爸在静态代码块");
    }

    public static int factor = 25;

    public Father()
    {
        System.out.println("我是爸爸~");
    }
}
class Son extends Father
{
    static 
    {
        System.out.println("儿子在静态代码块");
    }

    public Son()
    {
        System.out.println("我是儿子~");
    }
}
public class InitializationDemo
{
    public static void main(String[] args)
    {
        System.out.println("爸爸的岁数:" + Son.factor);  //入口
    }
}

思考一下,上面的代码最后的输出结果是什么?

最终的输出结果是:

爷爷在静态代码块
爸爸在静态代码块
爸爸的岁数:25

也许会有人问为什么没有输出「儿子在静态代码块」这个字符串?

这是因为对于静态字段,只有直接定义这个字段的类才会被初始化(执行静态代码块)。因此通过其子类来引用父类中定义的静态字段,只会触发父类的初始化而不会触发子类的初始化。

对面上面的这个例子,我们可以从入口开始分析一路分析下去:

首先程序到 main 方法这里,使用标准化输出 Son 类中的 factor 类成员变量,但是 Son 类中并没有定义这个类成员变量。于是往父类去找,我们在 Father 类中找到了对应的类成员变量,于是触发了 Father 的初始化。

但根据我们上面说到的初始化的 5 种情况中的第 3 种(当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化)。

我们需要先初始化 Father 类的父类,也就是先初始化 Grandpa 类再初始化 Father 类。于是我们先初始化 Grandpa 类输出:「爷爷在静态代码块」,再初始化 Father 类输出:「爸爸在静态代码块」。

最后,所有父类都初始化完成之后,Son 类才能调用父类的静态变量,从而输出:「爸爸的岁数:25」。

怎么样,是不是觉得豁然开朗呢。

我们再来看一下一个更复杂点的例子,看看输出结果是啥。

 

class Grandpa
{
    static
    {
        System.out.println("爷爷在静态代码块");
    }

    public Grandpa() {
        System.out.println("我是爷爷~");
    }
}
class Father extends Grandpa
{
    static
    {
        System.out.println("爸爸在静态代码块");
    }

    public Father()
    {
        System.out.println("我是爸爸~");
    }
}
class Son extends Father
{
    static 
    {
        System.out.println("儿子在静态代码块");
    }

    public Son()
    {
        System.out.println("我是儿子~");
    }
}
public class InitializationDemo
{
    public static void main(String[] args)
    {
        new Son();  //入口
    }
}

输出结果是:

爷爷在静态代码块
爸爸在静态代码块
儿子在静态代码块
我是爷爷~
我是爸爸~
我是儿子~

怎么样,是不是觉得这道题和上面的有所不同呢。

让我们仔细来分析一下上面代码的执行流程:

首先在入口这里我们实例化一个 Son 对象,因此会触发 Son 类的初始化,而 Son 类的初始化又会带动 Father 、Grandpa 类的初始化,从而执行对应类中的静态代码块。

因此会输出:「爷爷在静态代码块」、「爸爸在静态代码块」、「儿子在静态代码块」。

当 Son 类完成初始化之后,便会调用 Son 类的构造方法,而 Son 类构造方法的调用同样会带动 Father、Grandpa 类构造方法的调用,最后会输出:「我是爷爷~」、「我是爸爸~」、「我是儿子~」。

看完了两个例子之后,相信大家都胸有成足了吧。

下面给大家看一个特殊点的例子,有点难哦!

 

public class Book {
    public static void main(String[] args)
    {
        staticFunction();
    }

    static Book book = new Book();

    static
    {
        System.out.println("书的静态代码块");
    }

    {
        System.out.println("书的普通代码块");
    }

    Book()
    {
        System.out.println("书的构造方法");
        System.out.println("price=" + price +",amount=" + amount);
    }

    public static void staticFunction(){
        System.out.println("书的静态方法");
    }

    int price = 110;
    static int amount = 112;
}

上面这个例子的输出结果是:

书的普通代码块
书的构造方法
price=110,amount=0
书的静态代码块
书的静态方法

下面我们一步步来分析一下代码的整个执行流程。

在上面两个例子中,因为 main 方法所在类并没有多余的代码,我们都直接忽略了 main 方法所在类的初始化。

但在这个例子中,main 方法所在类有许多代码,我们就并不能直接忽略了。

当 JVM 在准备阶段的时候,便会为类变量分配内存和进行初始化。此时,我们的 book 实例变量被初始化为 null,amount 变量被初始化为 0。

当进入初始化阶段后,因为 Book 方法是程序的入口,根据我们上面说到的类初始化的五种情况的第四种(当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类)。所以JVM 会初始化 Book 类,即执行类构造器 。

JVM 对 Book 类进行初始化首先是执行类构造器(按顺序收集类中所有静态代码块和类变量赋值语句就组成了类构造器 ),后执行对象的构造器(按顺序收集成员变量赋值和普通代码块,最后收集对象构造器,最终组成对象构造器 )。

对于 Book 类,其类构造方法()可以简单表示如下:

static Book book = new Book();
static
{
    System.out.println("书的静态代码块");
}
static int amount = 112;

于是首先执行static Book book = new Book();这一条语句,这条语句又触发了类的实例化。于是 JVM 执行对象构造器 ,收集后的对象构造器 代码:

{
    System.out.println("书的普通代码块");
}
int price = 110;
Book()
{
    System.out.println("书的构造方法");
    System.out.println("price=" + price +", amount=" + amount);
}

于是此时 price 赋予 110 的值,输出:「书的普通代码块」、「书的构造方法」。而此时 price 为 110 的值,而 amount 的赋值语句并未执行,所以只有在准备阶段赋予的零值,所以之后输出「price=110,amount=0」。

当类实例化完成之后,JVM 继续进行类构造器的初始化:

static Book book = new Book();  //完成类实例化
static
{
    System.out.println("书的静态代码块");
}
static int amount = 112;

即输出:「书的静态代码块」,之后对 amount 赋予 112 的值。

到这里,类的初始化已经完成,JVM 执行 main 方法的内容。

public static void main(String[] args)
{
    staticFunction();
}

即输出:「书的静态方法」。

 

方法论

从上面几个例子可以看出,分析一个类的执行顺序大概可以按照如下步骤:

1.确定类变量的初始值。在类加载的准备阶段,JVM 会为类变量初始化零值,这时候类变量会有一个初始的零值。如果是被 final 修饰的类变量,则直接会被初始成用户想要的值。

2.初始化入口方法。当进入类加载的初始化阶段后,JVM 会寻找整个 main 方法入口,从而初始化 main 方法所在的整个类。当需要对一个类进行初始化时,会首先初始化类构造器(),之后初始化对象构造器()。

3.初始化类构造器。JVM 会按顺序收集类变量的赋值语句、静态代码块,最终组成类构造器由 JVM 执行。

4.初始化对象构造器。JVM 会按照收集成员变量的赋值语句、普通代码块,最后收集构造方法,将它们组成对象构造器,最终由 JVM 执行。

如果在初始化 main 方法所在类的时候遇到了其他类的初始化,那么就先加载对应的类,加载完成之后返回。如此反复循环,最终返回 main 方法所在类。

 

 

 

 

锂电池充电器电路设计 里面有电路 锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。 立即下载

相关推荐

MTK平台TP驱动设备树与GPIO配置实战解析

本文详细解析了MTK平台TP驱动开发中的设备树与GPIO配置实战。通过DCT工具配置GPIO引脚,结合设备树节点定义触摸参数,并分享驱动移植、编译调试技巧及常见问题解决方案,帮助开发者快速掌握MTK触摸驱动开发核心。

ice55的博客 234

模块已加载,但找不到入口点DLLRegisterServer

模块已加载,但找不到入口点DLLRegisterServer 通常在运行中注册动态库文件:regsvr32 xxx.dll (按回车键执行命令)都能顺利通过。 但有时也会报出异常: ​ 模块“xxx.dll”已加载,但找不到入口点DLLRegisterServer。请确保xxx.dll为有效的DLL或OCX文件,然后重试。 首先确保dll文件放在正确的位置: 32位系统将dll文件放在C:\Windows\System32 文件夹内。64位系统将dll文件放在C:\Windows\System32 文件夹

chenHARDEN的博客 18万+

人工智能在高中教育中的应用现状剖析与挑战应对

人工智能在高中教育中的应用现状剖析与挑战应对

燕鹏 1338

一文带你吃透Java代码执行过程:JVM加载字节码+解释执行+编译执行

前本节简单介绍Java代码执行过程,JVM在执行Java代码时所做的工作,以及JVM是如何设计的。Java代码执行的过程简单可以分为以下几步:1)Java代码被编译成字节码。2)(可选)字节码被AOT编译器编译成可执行文件(该功能在JDK 17中被废弃)。3)通过JVM执行字节码或者可执行文件。JVM作为一个程序,主要包含以下功能:1)JVM加载并解析字节码,或者JVM加载可执行文件,并解析可执行文件。

2401_83384536的博客 3060

Matcap与菲涅尔

菲尼尔效果(简化版公式):fresnel = base + scale*((1-v*n)^power)透明队列为后前渲染,不关闭深度写入则会覆盖之前的像素,导致混合不了。y的值为0~1,根据x3返回对应y值。两色混合做个demo看看!混合为什么要关闭深度写入?

weixin_62773441的博客 372

SAP OBYC自动过账全解析:从BSX到WRX的会计科目配置指南

本文深入解析SAP OBYC自动过账功能,从BSX到WRX的会计科目配置全流程,涵盖评估分组代码、事务码和评估类等核心概念。通过实战案例展示如何实现库存变动到财务过账的自动化流转,提升企业财务数据的准确性和效率。

weixin_29239279的博客 418

Java 类加载:字节码加载到Jvm中

前言 生成字节码后,这些数据如何加载到jsm中,并怎么存储成为了问题,本文主要研究一下这个内容。 加载到jvm 内存中 通过javac 转换成.class 字节码文件,这个时候计算机还是不能直接识别的,由jvm加载class文件,JVM的类加载是通过ClassLoader及其子类来完成的,再翻译成二进制指令,Java字节码的执行是由JVM解释器引擎来完成,类的层次关系和加载顺序可以由下图来描述: ...

笔记小屋 3174

eDP、DP与HDMI——现代显示接口的核心解析

eDP、DP和HDMI各有千秋:eDP以嵌入式设备的低功耗见长,DP凭借开放生态和高带宽成为专业领域首选,而HDMI则依靠庞大的消费电子生态稳居家庭市场。未来,随着Type-C接口的普及和超高清内容的爆发,三者的技术边界可能进一步融合,但各自的核心优势仍将长期共存。对于用户而言,选择接口需基于设备需求——游戏玩家青睐HDMI的VRR,设计师依赖DP的多屏扩展,而轻薄本则离不开eDP的紧凑设计。

麟的博客 8411

JVM学习-底层字节码的执行过程

静态方法不需要对象来调用,直接调用即可,如果使用对象调用静态方法,那么在底层的字节码指令中会先让对象的引用入栈,准备进行方法调用时发现是一个静态方法,那么就会将这个对象的引用弹出,然后直接通过invokestatic调用静态方法,这就会多执行一次入栈和弹出操作。所以,如果将实现类换成Cat,那么所创建的对象的对象头中的类型指针指向的就是Cat.class,然后从Cat类的虚方法表中找到Cat的say方法地址进而去调用。倘若没有dup复制,那么在构造完成后就会将仅有的对象引用弹出,就无法赋给变量。

qq_65568592的博客 1254

强化学习代码实现PPO

梯度更新:通过截断(clipping)限制策略更新幅度,避免策略变化过大影响稳定性。首先是数据预处理,将相关数据(状态、采取的动作、状态奖励、下一个状态)放到gpu上。根据当前状态 state,利用策略网络生成每个动作的概率分布 probs。2. 修改了策略模型的输出,从每个动作的概率分布变成了动作的均值和方差。1. 修改了动作空间,离散空间变成了连续空间,使用正太分布来采样。3. 修改了动作的ratio的计算,从离散分布变成了正太分布计算。Update函数:通过经验缓冲数据来优化策略模型和价值模型。

wlxsp的博客 635

从零到一:AIGC+Unity3D打造动态天空盒的实战指南

本文详细介绍了如何利用AIGC技术结合Unity3D打造动态天空盒的实战指南。通过AIGC生成360全景图,再集成到Unity3D中,实现高效、多样化的天空盒效果。文章涵盖了从AIGC全景图生成、工作流搭建到Unity场景集成的完整流程,并提供了代码示例和优化建议,帮助开发者快速掌握这一技术。

weixin_29021291的博客 603

....已加载,找不到入口点DllRegisterServer

今天在装Python遇到一个问题,安装完成后python.exe打开报错,提示 “api-ms-win-crt-runtime-l1-1-0.dll”找不到,后来重新找了个这个dll进行注册, 提示如下(找不到入口点DllRegisterServer): 百度了个各种方式之后还是没解决,最后有个网友说去掉注册表开机自启动项,果然重启了下好了。 办法: HKEY_CURRENT_USER\Soft...

~初出茅庐~ 的博客 4万+

【花雕学编程】Arduino FOC 之AS5048A磁编码器模块

您的硬件平台、使用场景和Arduino版本可能影响使用方法的选择。在Arduino平台上实现FOC可以提供平滑的运行和高度的扭矩、速度和位置控制,它通过精确控制电机的电流和电压来实现高效率、高精度和低噪声的操作。5、创新:Arduino可以让你用电子的方式来表达你的创意和想象,你可以用Arduino来制作各种有趣和有用的项目,如机器人、智能家居、艺术装置等。1、高性能电机控制:FOC是一种高级的电机控制算法,可以精准控制PMSM(永磁同步电机)和BLDC(无刷直流)电机,实现平滑的转速和扭矩输出。

雕爷学编程 1496

JVM系列--虚拟机类加载机制

在准备阶段,变量已经赋过一次系统要求的初始值,而在初始化阶段,则是根据程序员通过程序制定的主观计划去初始化类变量和其他资源。

qq_32473523的博客 1360

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

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

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

m0_74969835的博客 1730

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

JVM字节码与类的加载——类的加载过程详解

加载(Loading)阶段、链接(Linking)阶段、初始化(Initialization)阶段、类的使用(Using)、类的卸载(Unloading)

码说芯语的博客 1112

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Java 入门指南:JVM(Java虚拟机)——类的生命周期与加载过程

类从被加载到虚拟机内存中开始到卸载出内存为止,它的整个生命周期可以简单概括为 7 个阶段:加载、验证、准备、解析、初始化、使用和卸载。其中,验证、准备和解析这三个阶段可以统称为连接。 的生命周期除去使用和卸载,就是 Java 的类加载过程。这 5 个阶段一般是顺序发生的,但在动态绑定的情况下,解析阶段发生在初始化阶段之后。系统加载 Class 类型的文件主要三步:加载->连接->初始化。连接过程又可分为三步:验证->准备->解析。

热带鱼的技术博客 2183

JVM 每个类加载阶段分别做了什么?

链接阶段负责将加载到 JVM 中的二进制字节码进行校验、准备和解析,使其成为可以被 JVM 执行的运行时环境的一部分。简单来说,加载阶段就是把类的字节码从各种来源加载到 JVM 的方法区,并在方法区中创建该类的运行时数据结构,同时在内存中创建一个。验证阶段的核心是确保加载的类是安全的、合法的,防止恶意或错误的字节码破坏 JVM 的稳定性和安全性。初始化阶段是类加载过程的最后一步,也是真正开始执行类中定义的 Java 代码的阶段。方法,完成类变量的显式初始化和静态代码块的执行,使类真正可以使用。

专注于技术分享 698

JVM学习笔记:类加载机制

对于初始化阶段,虚拟机严格规范了。

RuaaaHaHa的博客 941

JVM类加载过程详解

类从被加载到虚拟机内存中开始到卸载出内存为止,它的整个生命周期可以简单概括为 7 个阶段:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)。其中,验证、准备和解析这三个阶段可以统称为连接(Linking)。

weixin_46425661的博客 1555

【JVM】类的加载过程详解

类的加载过程包括加载、链接、初始化、使用和卸载五个阶段。加载阶段将类的字节码文件读入内存并构建类模板对象;链接阶段包括验证、准备和解析三个子阶段,确保类的正确性和为静态变量分配内存;初始化阶段执行静态代码块和静态变量赋值;使用阶段通过实例化、调用方法等方式使用类;卸载阶段在类不再被引用且满足条件时,从内存中移除类的元数据和相关对象。整个过程由JVM规范严格定义,确保类的正确加载和使用。

白晨的博客 1359

JVM的类加载和字节码执行引擎

在上篇《JVM的Class文件结构》中,简单梳理了Class文件内容,然而这只是一个小小的开始。Class文件只是一个你所编写的程序信息的等价完备的存储,它是死的,若要让它活起来,就需要将Class文件加载到虚拟机中并运行。Class文件的类加载过程是怎样?进入到虚拟机中的Class文件信息又会以什么样的形式存储?虚拟机如何找到应该执行的方法?虚拟机如何执行Class文件中的字节码?这些都是需要思考

Public Static Void Main 1815

Java虚拟机(JVM)(6)—— 类的生命周期

本文主要介绍类的生命周期,以及在各阶段所执行的任务,希望对大家的日常工作有所帮助☺

知唔猪的博客 990

JVM笔记6:JVM类加载机制

实在是很难弄懂啊

怀揣梦想,努力前行 2万+

JVM 类加载全过程深度解析:加载、验证、准备、解析与初始化

本篇技术指南以 Doocs jvm 项目中「类加载的过程」一章为核心,系统讲解 JVM 类加载的 5 个阶段——加载、验证、准备、解析、初始化——各自要完成的工作、底层原理与边界情形,并结合仓库内「类加载的时机」「类文件结构」「类加载器」等章节交叉印证。读完本文,你将能准确区分"加载"与"类加载"这两个易混概念,理解 `public static int value = 123` 在准备阶段为何是

gitblog_01020的博客 453

JVM 类的加载篇

类的加载篇

qiuqiushuibx的博客 925
上一篇: SpringBoot 使用Swagger-ui get请求 date参数
下一篇: mysql 中 timestamp 长度的问题
不再简简单单
博客等级 码龄8年 21粉丝 76原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值