认真学习JVM中类加载过程

本文我们总结JVM中类加载器子系统关于类加载过程,这里默认是Oracle的Hotspot。
在这里插入图片描述

【1】类加载器子系统作用

类加载器子系统负责从文件系统或者网络中加载Class文件,class文件在文件开头有特定的文件标识。

ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engine决定。

加载的类信息存放于一块称为方法区的内存空间。除了类的信息外,方法区中还会存放运行时常量池信息,可能还包括字符串字面量和数字常量(这部分常量信息是Class文件中常量池部分的内存映射)

如下图所示类编译后class文件我们使用javap -v StackStruTest 查看字节码,其中Constant pool部分就会存储在方法区运行时常量池。
在这里插入图片描述

javap 是 Java Platform 的一个命令行工具,用于查看 Java 类文件的内容。它通常用来反汇编字节码并展示类文件的结构信息,包括类名、字段、方法和属性等。javap 是 Java 开发工具包 (JDK) 的一部分,因此如果你安装了 JDK,那么你就可以使用 javap。

【2】类加载器ClassLoader角色

如下图所示装载Car.class文件。

  • class file存在于本地硬盘上,可以理解为设计师画在纸上的模板,而最终这个模板在执行的时候是要加载到JVM当中来根据这个文件实例化出n个一模一样的实例。
  • class file加载到JVM中,被称为DNA元数据模板,放在方法区。
  • 在.class文件->JVM->最终成为元数据模板,此过程就要一个运输工具(类装载器Class Loader),扮演一个快递员的角色。
    在这里插入图片描述

【3】类的加载过程

例如下面的一段简单的代码

public class HelloLoader {public static void main(String[] args) {System.out.println("我已经被加载啦");}
}

它的加载过程是怎么样的呢?
在这里插入图片描述
完整的流程图如下所示:

在这里插入图片描述

【4】类加载过程-加载

  1. 通过一个类的全限定名获取定义此类的二进制字节流

  2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构

  3. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口

加载class文件的方式

  • 从本地系统中直接加载
  • 通过网络获取,典型场景:Web Applet
  • 从zip压缩包中读取,成为日后jar、war格式的基础
  • 运行时计算生成,使用最多的是:动态代理技术
  • 由其他文件生成,典型场景:JSP应用从专有数据库中提取.class文件,比较少见
  • 从加密文件中获取,典型的防Class文件被反编译的保护措施

【5】类加载过程-链接

链接阶段包括验证、准备和解析。

① 验证 Verify

目的在于确保Class文件的字节流中包含信息符合当前虚拟机要求,保证被加载类的正确性,不会危害虚拟机自身安全。

主要包括四种验证,文件格式验证,元数据验证,字节码验证,符号引用验证。

如下图所示,我们查看16进制的class文件时(可以使用PXBinaryViewer查看),开头几个字符是CA FE BA BE 来表明其是可以运行在JVM上的。
在这里插入图片描述
如果出现不合法的字节码文件,那么将会验证不通过。

② 准备 Prepare

  • 为类变量分配内存并且设置该类变量的默认初始值,即零值。

  • 这里不包含用final修饰的static,因为final在编译的时候就会分配了,准备阶段会显式初始化;

  • 这里不会为实例变量分配初始化,类变量会分配在方法区中,而实例变量是会随着对象一起分配到Java堆中。

零值:整数类型(int, short, byte, long)0 ; 浮点数类型(float, double)0.0 ; boolean false ;字符类型(char) \u0000 ; 引用类型(如对象、数组等) null 。

public class HelloApp {private static int a = 1;  // 准备阶段为0,在下个阶段,也就是初始化的时候才是1public static void main(String[] args) {System.out.println(a);}
}

上面的变量a在准备阶段会赋初始值,但不是1,而是0。

③ 解析 Resolve

  • 将常量池内的符号引用转换为直接引用的过程。

  • 事实上,解析操作往往会伴随着JVM在执行完初始化之后再执行。

  • 符号引用就是一组符号来描述所引用的目标。符号引用的字面量形式明确定义在《java虚拟机规范》的class文件格式中。直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。

  • 解析动作主要针对类或接口、字段、类方法、接口方法、方法类型等。对应常量池中的CONSTANT Class info、CONSTANT Fieldref info、CONSTANT Methodref info等

【6】类加载过程-初始化

  • 初始化阶段就是执行类构造器方法 <clinit>() 的过程。

  • 此方法不需定义,是javac编译器自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并而来。

    • 也就是说如果类中有静态变量或静态代码块,则自动有clinit方法。
  • 构造器方法中指令按语句在源文件中出现的顺序执行。

  • <clinit>() 不同于类的构造器。(关联:构造器是虚拟机视角下的 <init>()

  • 若该类具有父类,JVM会保证子类的 <clinit>() 执行前,父类的 <clinit>() 已经执行完毕。

  • 虚拟机必须保证一个类的 <clinit>() 方法在多线程下被同步加锁。

关于涉及到父类时候的变量赋值过程。

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) {System.out.println(Son.b);}
}

输出结果为 2。也就是说首先加载ClinitTest1的时候,会找到main方法,然后执行Son的初始化。但是Son继承了Father,因此需要首先执行Father的初始化,同时将A赋值为2。

我们通过jclasslib Bytecode Viewer(可以单独安装也可以idea装插件)查看Father类的<clinit>()方法。首先我们看到原来的值被赋值成1,然后又被复制成2,最后返回:

iconst_1
putstatic #2 <com/atguigu/java/chapter02/ClinitTest1$Father.A>
iconst_2
putstatic #2 <com/atguigu/java/chapter02/ClinitTest1$Father.A>
return

在这里插入图片描述

先选择编译后的class文件,然后在View-Show Bytecode With Jclasslib进行查看。

在这里插入图片描述

Son的<clinit>()方法:获取静态变量A的值赋值给静态变量B。

0 getstatic #2 <com/atguigu/java/ClinitTest1$Son.A : I>
3 putstatic #3 <com/atguigu/java/ClinitTest1$Son.B : I>
6 return

在这里插入图片描述

ClinitTest1的main方法:

0 getstatic #2 <java/lang/System.out : Ljava/io/PrintStream;>
3 getstatic #3 <com/atguigu/java/ClinitTest1$Son.B : I>
6 invokevirtual #4 <java/io/PrintStream.println : (I)V>
9 return

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/392778.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一款一站式、开源、高质量的数据提取工具,支持:PDF 文档、网页和电子书提取

大家好&#xff0c;今天给大家分享的是一款一站式、开源、高质量的数据提取工具MinerU&#xff0c;主要包含以下功能: Magic-PDF PDF 文档提取 Magic-Doc 网页与电子书提取 项目介绍 Magic-PDF 简介 Magic-PDF 是一款将 PDF 转化为 markdown 格式的工具。支持转换本地文档…

ABAP+json格式数据转换时参数为空没传值

CALL METHOD /UI2/CL_JSON>SERIALIZE 我们在ABAP传输json格式数据到外围系统时&#xff0c;会用到这个类方法 /UI2/CL_JSON>SERIALIZE CALL METHOD /UI2/CL_JSON>SERIALIZEEXPORTINGDATA LO_DATACOMPRESS XPRETTY_NAME /UI2/CL_JSON>PRETTY_M…

【Linux】网络基础_3

文章目录 十、网络基础5. socket编程socket 常见APIsockaddr结构简单的UDP网络程序 未完待续 十、网络基础 5. socket编程 socket 常见API // 创建 socket 文件描述符 (TCP/UDP, 客户端 服务器) int socket(int domain, int type, int protocol);// 绑定端口号 (TCP/UDP, 服…

tcpdump使用指南

tcpdump 是一款强大的网络抓包工具&#xff0c;它使用 libpcap 库来抓取网络数据包&#xff0c;这个库在几乎在所有的 Linux/Unix 中都有。 # 1. 基于IP地址过滤 # 根据源ip进行过滤 $ tcpdump -i eth2 src 192.168.10.100# 根据目标ip进行过滤 $ tcpdump -i eth2 dst 192.16…

江协科技51单片机学习- p33 PWM呼吸灯和直流驱动电机调速

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

还在花大几千定制 AI Agent ?来这里分分钟让你实现 Agent 自由!海量模板任你挑选!

大家好&#xff0c;又见面了&#xff0c;最近很多人都对 AI Agent 感兴趣&#xff0c;有的朋友想花大几千进行 Agent 定制&#xff0c;当时就被我劝住了&#xff0c;我想这不是免费了吗&#xff1f;怎么还花钱呢&#xff1f;纯纯的信息差呀&#xff01; 同时我也收到了几位伙伴…

VTK8.2.0编译(Qt 5.14.2+VS2017)

VTK8.2.0编译&#xff08;Qt 5.14.2VS2017&#xff09; 关于Qt和MSVC的安装&#xff0c;可以参考文章&#xff08;QtMSVC2017&#xff09;。 本篇VTK在QtMSVC的配置下的编译。VTK 以8.2.0为例。 一、环境变量的配置 我们打开电脑的环境变量&#xff0c;可以看到没有Qt相关的…

C#串口通信的实现

1、实现代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO.Ports; using System.Linq; using System.Security.Cryptography; using System.Security.Policy; using System.Text…

人工智能时代,程序员如何保持核心竞争力?

在人工智能时代&#xff0c;程序员如何保持核心竞争力&#xff1f; 在今天这个人工智能迅速发展的时代&#xff0c;程序员面临着前所未有的机遇和挑战。随着AIGC&#xff08;如ChatGPT、MidJourney、Claude等&#xff09;大语言模型的兴起&#xff0c;以及AI辅助编程工具的普及…

Axure八大优质Web端系统框架模版

在当今数字化转型的浪潮中&#xff0c;Axure作为一款强大的原型设计工具&#xff0c;以其快速、直观和易用的特点&#xff0c;成为了众多设计师和产品经理的首选。本文将详细介绍六套基于Axure制作的智慧系统原型框架模版&#xff0c;包括智慧园区、智慧社区、智慧乡村、智慧驾…

Oracle SQL Developer 连接第三方数据库

首先Oracle SQL Developer除了支持连接Oracle数据库外&#xff0c;还支持连接第三方数据库&#xff0c;包括&#xff1a; Amazon RedshiftHiveIBM DB2MySQLMicrosoft SQL ServerSybase Adaptive ServerPostgreSQLTeradataTimesTen 首先&#xff0c;你需要在菜单Tools > Pr…

C++笔试练习笔记【5】:最小花费爬楼梯(有题目链接) 初识动态规划

文章目录 题目思路代码 动态规划简介**一、什么是动态规划****二、动态规划的应用场景****三、动态规划的基本步骤****四、动态规划的优缺点** 题目 题目链接&#xff1a;https://www.nowcoder.com/practice/9b969a3ec20149e3b870b256ad40844e?tpld230&tpld39751&ru/…

IT课程学习搭子

各种IT课程齐全可学&#xff0c;价格你绝对想不到&#xff0c;相比于培训班有以下优势&#xff1a; 1、避免被割韭菜&#xff0c;避免踩坑&#xff0c;避免交智商税&#xff0c;最低的成本学最有价值的课&#xff0c;同时又能达到比培训班更好的效果 2、收徒&#xff0c;带你学…

【Linux课程学习】:对于权限的理解(粘滞位)

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;Linux课程学习 &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 这篇文章主要理解权限的概念&#xff0c;以及如何更改…

KubeVirt虚拟机存储及网络卸载加速解决方案

1. 方案背景 1.1. KubeVirt介绍 随着云计算和容器技术的飞速发展&#xff0c;Kubernetes已成为业界公认的容器编排标准&#xff0c;为用户提供了强大、灵活且可扩展的平台来部署和管理各类应用。然而&#xff0c;在企业的实际应用中&#xff0c;仍有许多传统应用或遗留系统难…

AOP学习

AOP概述 AOP&#xff08;Aspect Oriented Programming&#xff09;&#xff1a;⾯向切⾯编程&#xff0c;它是⼀种思想&#xff0c;它是对某⼀类事情的集中处理。 什么是SpringAOP? ⽽ AOP 是⼀种思想&#xff0c;⽽ Spring AOP 是⼀个框架&#xff0c;提供了⼀种对 AOP 思…

【Vue3】element-plus中el-tree的递归处理赋值回显问题

由于项目是从0-1开始构建的rbac都需要重新构建对接 所以涉及到了权限管理和菜单管理 整体思路很简单&#xff1a;初始化树 -> 处理 el-tree 回显 -> 递归处理所有层级菜单选中的id 不处理情况下&#xff1a; 只要勾选一个子节点&#xff0c;回来接收到的父节点数据 会…

Java面试题——第三篇(JVM)

1. 什么情况下会发生栈内存溢出 栈是线程私有的&#xff0c;他的生命周期和线程相同&#xff0c;每个方法在执行的时候都会创建一个栈帧&#xff0c;用来存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行完成的过程&#xff0c;就对应着一个栈帧…

剪映怎么剪辑视频?2024年视频剪辑新手必读指南!

在快节奏的工作里&#xff0c;掌握快速剪辑视频的技巧真的很有用。不管是要做个产品展示、录制培训材料&#xff0c;还是制作社交媒体上的内容&#xff0c;有一款好用的视频剪辑软件&#xff0c;工作效率立马提升好几个档次。咱们今天就先来聊聊剪映怎么剪辑视频&#xff1f;如…

如果忘了Linux密码如何重置?

忘记密码是我们常会遇到的情况之一&#xff0c;无论是在操作系统、网站账户、手机、电子邮件还是其他渠道上。 忘记密码是我们常会遇到的情况之一&#xff0c;无论是在操作系统、网站账户、手机、电子邮件还是其他渠道上。有时候如果密码需要符合特定的复杂性要求&#xff0c;…