【JVM】类加载

这篇具有很好参考价值的文章主要介绍了【JVM】类加载。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

类加载是运行时环境的一个重要核心功能。
类加载的主要功能:把 .class 文件加载到内存中构建成为类对象。

什么时候会进行类加载呢 ?
不是说 java 程序一运行,就把所有的类都加载了,而是用到的时候再加载。(懒汉模式)

那什么时候算是用到了呢 ?

  1. 创建类的实例
  2. 调用类的静态方法 / 静态属性
  3. 加载子类,就会先加载父类

类的生命周期是这样的:

【JVM】类加载,JVM,jvm

其中前 5 步是固定的顺序并且也是类加载的过程,其中 中间的 3 步都属于连接,所以对于类加载来
说总共分为以下几个步骤:

  1. 加载 Loading
  2. 连接 Linking:
    验证 Verification
    准备 Preparation
    解析 Resolution
  3. 初始化 Initialization

下面我们分别来看每个步骤的具体执行内容。

一. 加载 Loading

“加载”(Loading)阶段是整个“类加载”(Class Loading)过程中的一个阶段,在加载 Loading 阶段,Java虚拟机需要完成以下三件事情:

  1. 通过一个类的全限定名来获取定义此类的二进制字节流 (.class 文件)。
  2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。虚拟机会将类文件的二进制字节流解析并转化为方法区
    (Java 8之后称为元空间 Metaspace)中的运行时数据结构。这些数据结构包括类的字段、方法、父类、接口、常量池等信息。
  3. 在第2步之后,虚拟机会创建一个 java.lang.Class 对象,用于表示刚刚加载的类。这个java.lang.Class对象包含了对类的引用、方法区数据结构的指针等,它是在Java程序中访问类元信息的入口。这个对象的生成是为了让Java程序能够在运行时通过反射等手段访问和操作加载的类。

.class 文件就是把 .java 文件中核心信息都表达出来,只不过组织格式发生了变化。
Loading 会把从 .class 文件中解读到的信息初步填写到类对象中。

二. 连接 Linking

1. 验证 Verification

验证是连接阶段的第一步,这一阶段的目的是确保 Class文件的字节 流中包含的信息符合《Java虚拟机规范》的全部约束要求,保证这些信 息被当作代码运行后不会危害虚拟机自身的安全。

验证选项:

  • 文件格式验证
  • 字节码验证
  • 符号引用验证…

如果不符合规范类加载就会失败,抛出异常。

2. 准备 Preparation

准备阶段是正式为类中定义的变量(即静态变量,被static修饰的变量)分配内存并设置类变量初始值的阶段。
注意这里面设置的初始值指的是默认值
比如此时有这样一行代码:

public static int value = 123;

它是初始化 value 的 int 值为 0,而非 123。

3. 解析 Resolution

解析阶段是 Java 虚拟机将常量池内的符号引用替换为直接引用的过程,也就是初始化常量的过程。

注意:常量池中不是只有 字符串常量

运行时常量池: 存放字面量与符号引用。

  • 字面量 : 字符串常量 (JDK 8 移动到堆中) 、final常量、基本数据类型的值。
  • 符号引用 : 类和结构的完全限定名、字段的名称和描述符、方法的名称和描述符。

举个栗子:

class Example {
    public int count = 0;
    public void increment() {
        count++;
    }
}

public class Main {
    public static void main(String[] args) {
    	Example e = new Example();
        int currentCount = e.count; // 引用Example类的count字段
        e.increment(); // 调用Example类的increment方法
    }
}
  • 解析 e.count:在这个步骤中,虚拟机将符号引用 e.count 解析为实际的内存地址,以便能够访问count字段的值。

  • 解析 e.increment():虚拟机将符号引用 e.increment() 解析为实际的方法内存地址,以便能够正确地调用increment方法。

到这里, 你可能有些疑惑 ?这个实例属性 count 不是在运行阶段创建对象时才分配空间 ?但是类加载阶段不是先于运行阶段么 ?

  • 确实,Resolution 阶段的主要任务是将符号引用替换为实际的直接引用,但这些直接引用在Resolution 阶段只是一种占位符,它们在内存中并不代表实际的对象或实例属性。
  • 直到对象实例化时,实例属性的内存空间才是真正有效的,并且可以存储实际的属性值。Resolution 阶段的替换只是为了确保在运行时可以正确地引用这些属性,但不会创建对象实例或分配实例属性的内存空间。

这个分离的设计有助于节省内存和提高性能,因为不是所有类都会被实例化,只有在需要时才会分配内存。

但是对于类名, 方法名, 静态属性的符号引用替换为直接引用是没有这个问题的。

三. 初始化 Initialization

执行类的静态初始化。在类首次被主动使用(例如,创建对象实例、访问静态字段或调用静态方法)时触发。
在这个阶段,虚拟机会初始化类中的静态字段和静态代码块,确保它们按照指定的顺序被正确地初始化。

此时上述的代码:

public static int value = 123;

此时 value 的值才是 123.文章来源地址https://www.toymoban.com/news/detail-730801.html

到了这里,关于【JVM】类加载的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【JVM】类加载

    类加载是 运行时环境 的一个重要核心功能。 类加载的主要功能:把 .class 文件加载到内存中构建成为类对象。 什么时候会进行类加载呢 ? 不是说 java 程序一运行,就把所有的类都加载了,而是用到的时候再加载。(懒汉模式) 那什么时候算是用到了呢 ? 创建类的实例 调用

    2024年02月07日
    浏览(33)
  • 【JVM】类加载器

    类加载器(ClassLoader)是Java虚拟机提供给应用程序去实现获取类和接口字节码数据的技术。 类加载器分为两类: Java代码中实现的类加载器 JVM底层源码实现的类加载器 jdk8和8之后版本的类加载器的设计差别较大,jdk8及之前的版本中默认的类加载器有如下几种: JVM底层实现

    2024年02月07日
    浏览(37)
  • JVM类加载器

    类加载器虽然只用于实现类的加载动作 ,但它在Java程序中起到的作用却远超类加载阶段。 对于 任意一个类,都必须由加载它的类加载器和这个类本身一起共同确立其在Java虚拟机中的唯一性 ,每一个类加载器,都拥有一个独立的类名称空间。这句话可以表达得更通俗一些:

    2024年02月09日
    浏览(36)
  • JVM类加载过程

    类加载Class类型的文件主要三步: 加载-链接-初始化 。链接过程又可以分为三步: 验证-准备-解析 。 将类的字节码载入方法区中,内部采用 C++ 的 instanceKlass 描述 java 类,它的重要 field 有: _java_mirror 即 java 的类镜像,例如对 String 来说,就是 String.class,作用是把 klass 暴 露

    2023年04月23日
    浏览(39)
  • JVM——类加载器

    类加载过程: 加载-连接-初始化 。连接过程又可分为三步: 验证-准备-解析 。 一个非数组类的加载阶段(加载阶段获取类的二进制字节流的动作)是可控性最强的阶段,这一步我们可以去完成还可以自定义类加载器去控制字节流的获取方式(重写一个类加载器的 loadClass() 方

    2024年02月12日
    浏览(31)
  • JVM类加载

    执行 javac -parameters -d . HellowWorld.java编译为 HelloWorld.class文件,根据 JVM 规范,类文件结构如下 原始代码如下: 字节码文件自己分析嫌慢,可以 执行指令javap -v filepath反编译命令 ,直接获取字节码指令更直观 问题:方法如何被执行的呢? ANS:原始代码编译成字节码文件-常量池载入运行

    2024年01月23日
    浏览(33)
  • JVM:类加载机制

    Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这个过程被称作虚拟机的类加载机制。 一个类型从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期将会经历 加载、验证

    2024年01月17日
    浏览(89)
  • JVM类加载机制

    自己编写的Java代码,是如何在各种各样的操作系统上运行起来的? Java文件通过javac编译成class文件,这种中间码被称为字节码,然后由jvm加载字节码,运行时解释器将字节码解释为一行行机器码来执行,在程序运行期间,即时编译器能会针对热点代码将该部分字节码编译成机

    2024年02月10日
    浏览(38)
  • JVM类加载机制(六)

    类加载器(ClassLoader)是 Java 虚拟机(JVM)的重要组成部分,负责将类的字节码加载到内存中并转换为可执行的 Java 类。类加载器的主要任务是根据类的名称查找字节码文件并加载到内存中,然后进行验证、准备和解析等操作,最终生成可执行的类。 类加载器的分类: 启动类

    2024年02月06日
    浏览(52)
  • JVM的类加载机制

    1、概述: JVM是Java语言实现跨平台的关键 ,Java语言的运行过程:         *.java通过编译器编译为*.class,通用字节码文件并不能直接被操作系统所识别,针对不同的操作系统可安装对应的JVM,JVM将字节码解释为当前平台所能识别的机器码实现“跨平台”。 JVM执行class文件

    2024年02月07日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包