java虚拟机原理:类加载过程详解

作者:韩曙亮 时间:2023-08-09 11:35:37 

目录
  • 一、Java 类加载过程

    • 1、字节码编译

    • 2、加载

    • 3、连接

    • 4、初始化

  • 总结

    一、Java 类加载过程

    1、字节码编译

    编写好 Java 源码 Student.java ,

    使用 javac 将上述 Java 源码编译成 Class 字节码文件 Student.class ,

    2、加载

    加载 : 通过 " 类加载子系统 " 将该字节码文件 , 加载到 Java 虚拟机内存中 的 方法区 , 然后开始执行 " 连接 " 操作 ,

    类加载时机 : Java 程序执行时 , 并不是一开始将所有的字节码文件都加载到内存中 , 而是用到时才进行加载 ;

    • 通过 new 关键字创建实例对象 ;

    • 通过 Class 反射 获取类 ;

    • 如 : Class.forName(“Xxx”) 获取类 ;

    • 序列化 / 反序列化 ;

    • 调用 clone 克隆对象 ;

    • 有 main 函数的类 , 会默认自动加载 ;

    • 调用子类 , 如果之前没有加载过父类 , 则 自动加载父类 ;

    3、连接

    连接操作 分为 3 3 3 个步骤 :

    • 验证 : 对 字节码文件 进行校验 , 查看该字节码格式是否正确 , 如 : 是否以 0xCAFEBABE 开头 , 字段表 , 方发表 , 属性表 等格式是否正确 , 进行校验 ;

    • 校验示例 : 假设校验如下字节码数据 , 原始数据是 【Java 虚拟机原理】Class 字节码二进制文件分析 一 ( 字节码文件附加信息 | 魔数 | 次版本号 | 主版本号 | 常量池个数 ) 二、字节码文件示例 章节中的 Java 源码 , Class 字节码 , 字节码附加信息 ;

    在 Student 构造方法中 , 会调用到 1: invokespecial #1 父类构造方法 , 如果父类有有参的构造方法且没有声明无参构造方法 , 子类必须实现一个相同参数的构造方法 , 否则就会报错 ;


    Constant pool:
      #1 = Methodref          #4.#17         // java/lang/Object."<init>":()V
    {
     public Student();
       descriptor: ()V
       flags: ACC_PUBLIC
       Code:
         stack=1, locals=1, args_size=1
            0: aload_0
            1: invokespecial #1                  // Method java/lang/Object."<init>":()V
            4: return
         LineNumberTable:
           line 1: 0
    }
    • 准备 : 在该阶段 , 在 方法区 中 , 为 类中的静态变量 进行内存划分 , 并对这些静态变量进行 默认值赋值 , 一般赋值 0 , null 等默认值 ; 即使静态变量 static int a = 5 已经有了赋值 , 但是在该阶段暂时给该静态变量赋值 0 ;

    • 解析 : 将 " 常量池 " 中的 " 符号引用 " 转为 " 直接引用 " ;

    符号引用 : 下面就是 常量池中的 符号引用 , 引用是 以符号的形式表示出来 的 , 这并不是内存中的引用 ; 直接引用 是 将 #1 = Methodref #4.#17 样式的 符号引用 转为 指向内存地址 的 指针引用 ; JVM 线程栈 的 栈帧 中的 动态链接 , 就是持有的一个指向内存的指针 , 该指针指向 栈帧 对应方法 在运行时 常量池中的 内存地址 ; 该内存地址是在 方法区 中的 ;


    Constant pool:
      #1 = Methodref          #4.#17         // java/lang/Object."<init>":()V
      #2 = Fieldref           #3.#18         // Student.name:Ljava/lang/String;
      #3 = Class              #19            // Student
      #4 = Class              #20            // java/lang/Object

    ( 分析的数据是 【Java 虚拟机原理】Class 字节码二进制文件分析 一 ( 字节码文件附加信息 | 魔数 | 次版本号 | 主版本号 | 常量池个数 ) 二、字节码文件示例 章节中的 Java 源码 , Class 字节码 , 字节码附加信息 ; )

    4、初始化

    初始化 : 对变量进行 指定赋值 ;

    如 : 有静态变量 static int a = 5 , 在 连接 过程中的 准备 阶段 , 为该变量赋值默认值 0 ; 在 初始化 阶段 , 为其赋值 代码 中设置的真正的 指定初始值 5 ;

    来源:https://blog.csdn.net/shulianghan/article/details/120126911

    标签:java,类加载
    0
    投稿

    猜你喜欢

  • Netty分布式Server启动流程服务端初始化源码分析

    2021-07-12 12:35:19
  • C# 拷贝数组的几种方法(总结)

    2023-09-14 06:50:17
  • JAVA验证身份证号码有效性的实例代码

    2021-08-20 13:52:06
  • java连接zookeeper实现zookeeper教程

    2022-09-19 03:04:35
  • JavaWeb入门教程之分页查询功能的简单实现

    2021-11-11 21:52:23
  • Flutter有无状态类与State及生命周期详细介绍

    2022-12-27 15:48:53
  • SpringBoot集成Shiro进行权限控制和管理的示例

    2022-12-31 19:23:21
  • Android App开发中创建Fragment组件的教程

    2022-05-18 04:34:38
  • Qt for Android开发实例教程

    2023-06-27 10:00:39
  • SpringBoot从yml配置文件中读常用参数值实例方法

    2021-07-01 11:12:04
  • java基础之String知识总结

    2022-09-24 16:25:20
  • C#中DataSet转化为实体集合类的方法

    2022-05-09 00:50:46
  • Java URL自定义私有网络协议

    2021-08-11 02:21:06
  • Spring(AbstractRoutingDataSource)实现动态数据源切换示例

    2022-05-23 07:05:08
  • java批量解析微信dat文件

    2022-12-26 01:53:28
  • Android自定义漂亮的圆形进度条

    2023-08-04 04:23:06
  • Android实现连连看游戏

    2021-08-22 09:51:17
  • Android 接收微信、QQ其他应用打开第三方分享功能

    2022-06-12 18:11:58
  • Druid基本配置及内置监控使用_动力节点Java学院整理

    2022-12-16 20:55:58
  • 深入学习Java单元测试(Junit+Mock+代码覆盖率)

    2021-06-17 00:39:13
  • asp之家 软件编程 m.aspxhome.com