JVM(一)

news2024/11/15 11:19:31
字节码文件的组成:

基础信息:魔数,字节码文件对应的java版本号,访问表示public final以及父类和接口 

常量池:保存了字符串常量,类或者是接口名,字段名,主要在接口中使用

字段:当前类或者是接口声明的字段信息

方法:当前类或者接口声明的方法信息,字节码指令

属性:指的是类的属性,源码的文件名以及类的列表

字节码文件中常量池的作用:避免相同的内容同时定义节省空间,不仅会使文件变得非常大,况且读取也会非常慢

可以看到字符串的引用存放的是7号的索引,点击常量池的索引,发现又是一个字面量

最后点击25就可以找到最终的字面量了

通过常量池节省字节码文件中的一部分空间,避免同样的数据出现多次

但是为什么字节码文件再进行设计这一块的时候,先通过字符串的引用找到字符串,再来通过字符串找到字面量呢?能不能直接通过字段来找到字面量呢?因为JAVA里面的字符串解析并加载中,需要将String类型加载到字符串常量池中

操作数栈是存放临时数据的地方,两个数相加运算都要放在操作数栈,最终结果都放在操作数栈中,局部变量表是存放方法中局部变量的位置,是在方法中声明的局部变量

下面就是局部变量表,底层是依靠数组来实现的,实际上是依靠你定义变量的顺序来声明数组下标的

istore_i:将操作数栈中的数据取出来放到局部变量表中的对应位置i,那么到底应该放在哪一个位置呢?应该在istrore后面加上一个数组下标,比如说istore_1就会将操作数栈中的内容放到局部变量表中的1号位置,局部变量表中的数据取出来之后,就没了

iload_i:从局部变量表的i位置复制一份取出数放到操作数栈中,最终操作数栈和局部变量表都是会有这个数据的;

iconst_data:将data数据放入操作数栈中

int i=0会拆解出iconst_0和istore_1这两个指令

i_add:将操作数栈中的顶部的两个数据进行相加,并将结果放入到操作数栈中

iinc 1 by 1:将局部变量表中的1号位置加1

JVM是如何执行的?

类加载器:加载class字节玛的内容到内存中

运行时数据区:负责管理JVM使用到的内存,比如说创建对象和销毁对象

方法区:常量,域信息,只有HotSpot虚拟机才有

执行引擎:将字节码文件中的内容解析成机器码,同时使用即时编译优化性能

本地方法接口:调用本地已经编译的方法,比如说虚拟机中已经提供好的C/C++的方法

翻译字节码:针对于字节码的指令进行解释执行

JIT编译器:针对于热点代码进行二次编译(将字节码中的字节码指令编译成机器指令)并将其缓存起来缓存在方法区中

类加载:

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

2)类加载器只是负责class文件的加载,至于它是否可以运行,那么则有执行引擎来决定

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

java虚拟机针对于class文件采用的是按需加载的方式,也就是说当需要使用该类的时候才会将他的class文件加载到内存中生成类对象,而且家在某一个类的class文件的时候,JAVA虚拟机采用的是双亲委派模型,会把请求交给父亲来处理,是一种任务委派模式

在类加载中使用synchronized加锁,向上委托检查,向下加载

1)避免类的重复加载

2)保护程序安全,防止核心API被随意篡改

在JVM中表示两个Class对象是否是同一个需要满足两个条件

1)两个类的完整类名必须完全一致,全限定包名和类名

2)加载这个类的classloader实例对象必须相同

换句话说,在JVM中,即使这两个类对象Class都西昂来源于同一个Class文件,悲痛一个虚拟几所加载,但是只要加载他们的ClassLoader实例对象不同,两个类对象也是不相同的

类加载的相关知识:

类的生命周期描述了一个类加载使用卸载的过程:

加载---链接---初始化----使用----卸载

1)loadding:

a)根据包的全限定包名+类名通过不同的渠道来找到对应的.class文件加载到内存中;

本地的字节码文件+动态代理生成的+网络

b)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构,就是将字节码的信息存放到方法区里面,方法区就是用来存放已被加载的类信息,常量,静态变量

c)在方法区中生成这个类的类对象,作为方法区中这个类的各种数据的访问入口

2)链接:

2.1)验证:class文件是以特定的文件符开始的,校验内容是否满足JAVA虚拟机规范;

a)文件格式验证:验证文件是否已特定字符开头,就是以特定的二进制文件开头

b)原信息校验:就是对一些基本信息进行校验,比如说类必须有父类

c)验证程序执行的语义:比如说方法中的指令执行中跳转到不正确的位置

d)符号引用验证:例如说有没有类中访问private修饰的方法

e)版本号检测:如果返回值是true,代表验证成功

class文件的主版本号要大于一个常量,代表所支持的最低版本号,这个常量默认是45代表JDK1.0,JDK的最高版本是52,况且父版本号是0

2.2)准备:为静态变量分配内存并设置初始化值为0值,是默认值的初值,就是防止程序员写出脑残代码,比如说给一个a没有赋初值,如果程序员进行后续操作打印a;

因为final修饰的静态变量,在准备阶段就直接复制初始值了,因为在编译期的时候直接就可以确定值

这里面不会针对于实例变量进行初始化,实例变量会随着对象一起被分配到JAVA的堆里面

2.3)解析:解析所作的操作就是将常量池中的符号引用替换成直接引用

符号引用就是在字节码文件中使用编号来访问字符串常量池中的内容,而直接引用不再使用编号,而是使用内存地址来直接访问具体的数据

3)初始化阶段:执行静态代码块中的代码并且会给静态变量赋初值

其实本质上初始化就是在执行字节码部分的中的clinit部分的字节码指令

iconst:将数字放入到操作数栈中

putstatic:将操作数栈中的数据放到静态变量中

如果将代码进行颠倒,clinit字节码指令执行的顺序和java中编写的顺序是一致的

下面来看一下哪几种方式会导致类的初始化:

1)当访问到一个类的静态变量或者是静态方法,注意变量是final修饰的并且等号右边是常量不会触发初始化

2)调用Class.forName(String className)获取到这个类的类对象的时候

3)new一个该类的对象的时候

4)执行Main方法的当前类

添加-XX:+TraceClassLoading参数可以打印出加载并且初始化的类

下面程序的输出结果是:

执行main函数,况且类加载只会执行一次,所以静态代码块也只会执行一次,先进行类加载DACBCB

clinit方法在特定的条件下不会出现,如下面几种情况是不会执行初始化指令的,也就不会生成clinit方法:

1)没有静态代码块况且没有静态变量赋值语句

2)有静态变量的声明但是没有赋值语句,public static int a;

3)静态变量的定义使用final关键字况且这份变量会在准备阶段直接进行初始化

在上面的情况下不会执行初始化操作

1)直接访问父类的静态变量,不会触发到子类的初始化,子类的clinit方法执行前会先执行父类的clinit方法

2)声明一个类以后,内部至少会存在一个这个类的构造器,也就是一定会出现init方法

访问父类的初始化变量只会初始化父类,因为a只是在父类中,此时打印的是a=1

第五步就是为了防止多个线程多次加载同一个类,从下面的代码中而可以看到类加载中的静态代码块只会执行一次,就相当于是一个加锁的过程,一个类在内存中加载一次即可,方法区在JDK1.8使用的是元空间,会使用直接内存缓存起来了,也就是说JAVA虚拟机在执行类加载的时候只会执行一次,只会调用一次clinit()方法

非法的前向引用:当一个定义的变量出现在静态代码块之后,是可以在静态代码块中赋值的,但是是不可以打印这个静态代码块的

 从下到上查找是否加载过,再从上向下进行记载

 

BootStrap:启动类加载器

 rt.jar:包含着java.lang中的String类这样就可以使用BootStrap类加载器来加载自己所扩展的类

1)将自己写的类打包成jar包

2)将自己写的jar包放在任意一个目录:C:/data

3)使用命令来进行扩展,选择添加虚拟机参数

ext目录:通用但是不重要

Appclassloader:在用户自己写的类和第三方依赖jar包的字节码文件

如何打破双亲委派模型? 
 

1)使用PC寄存器存储字节码指令地址有什么用呢?

为什么使用PC寄存器来记录当前线程执行的地址呢?

CPU需要不停的进行切换各个线程,这时候切换回来之后,就得知道下一条从哪里开始继续执行,JVM的字节码解释器就需要通过改变PC寄存器的值来确定下一条该执行啥样的字节码

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

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

相关文章

win10 wsl安装步骤

参考&#xff1a; 安装 WSL | Microsoft Learn 一、安装wsl 1.若要查看可通过在线商店下载的可用 Linux 发行版列表&#xff0c;请输入&#xff1a; wsl --list --online 或 wsl -l -o> wsl -l -o 以下是可安装的有效分发的列表。 使用 wsl.exe --install <Distro>…

知识体系图谱

知识体系图谱 最近更新简历的时候&#xff0c;有种好像去年到今年学了很多&#xff0c;但是都零零散散的&#xff0c;不成体系&#xff0c;就想着抽时间总结归纳一下知识体系&#xff0c;目前我个人的技术栈是这样的&#xff1a; 还是稍微有点乱&#xff0c;下一次更新的时候再…

HQChart支持的画图工具列表

HQChart支持的画图工具列表 线段类线段射线标价线垂直线箭头趋势线水平线水平线段平行射线平行线平行通道价格通道线M头W底头肩型波浪尺AB波浪尺箱型线涂鸦线段 图形类圆弧线矩形平行四边形三角形圆对称角度 文字类文本箭头NoteAnchoredTextPriceLabelPriceNote 其他江恩角度线…

Ubuntu下怎么配置vsftpd

2023年10月12日&#xff0c;周四中午 目录 首先要添加一个系统用户然后设置这个系统用户的密码给新创建的系统用户创建主目录启动vsftpd服务查看vsftpd服务的状态打开外界访问vsftpd服务所需的端口获取服务器的IP地址大功告成 首先要添加一个系统用户 useradd 用户名然后设置…

如何应对量化交易,个人股票账户如何实现量化程序化自动交易

目前股票量化交易是对个人账户开放的&#xff0c;如果你没开通&#xff0c;可能是没有找对渠道&#xff0c;很多券商的手机客户端是包含某些简易版的策略交易&#xff0c;如网格策略&#xff0c;自动止盈止损等&#xff0c;这些策略交易虽然简单、灵活性差&#xff0c;但也是量…

【数据安全】数据安全运维是什么意思?有什么意义?

随着数字化大力发展&#xff0c;保障企业重要资产数据的安全越发重要&#xff0c;因此衍生了数据安全运维工作。那你知道数据安全运维是什么意思&#xff1f;有什么意义&#xff1f; 数据安全运维是什么意思&#xff1f; 数据安全运维是将数据分析技术用于管理数据的过程&…

【萌新向】Sql Server保姆级安装教程-图文详解手把手教你安sql

首先打开百度&#xff0c;搜索sql server&#xff0c;找到图示词条&#xff0c;点击进去。 一般版本是需要付费的&#xff0c;正常开发可以使用免费版本【Express】&#xff0c;点击下载 下载完成后打开下载的文件。三个选项&#xff0c;我们选自定义方式。 选择语言和位置…

第四范式破发,AI大模型之殇?

9月28日&#xff0c;决策类AI独角兽第四范式敲钟挂牌港交所&#xff0c;发行价为55.60港元/股&#xff0c;IPO首日报收58.50港元/股&#xff0c;涨幅5.22%。不过也就日内富贵&#xff0c;在之后的几个交易日里&#xff0c;市值蒸发超20亿港元&#xff0c;截止目前&#xff0c;股…

Air001 TIM1高级定时器单脉冲输出模式使用

Air001 TIM1高级定时器单脉冲输出模式使用 ✨本例程基于合宙官方提供的标准库以及Demo工程作为验证参考。&#x1f4cd;官方提供的SDK包资源&#xff1a;https://gitee.com/openLuat/luatos-soc-air001&#x1f33f;想了解STM32高级定时器单脉冲输出模式了解可以参考阅读:https…

C++ 黑马程序员通讯录管理系统源码

/* 通讯录管理系统 通讯录是一个可以记录亲人、好友信息的工具。 本教程主要利用C来实现一个通讯录管理系统系统中需要实现的功能如下: 添加联系人:向通讯录中添加新人&#xff0c;信息包括 (姓名、性别、年龄、联系电话、家庭住址))最多记录1000人 显示联系人:显示通讯录中所有…

前端开发工具vscode

一、下载安装 https://code.visualstudio.com/ 二、安装插件 三、使用 ①、创建一个空目录 ②、利用vscode工具打开该目录 ③、将该目录设置为工作区 在工作区中添加文件&#xff0c;还可以进行浏览器访问&#xff08;提前安装了Live Server插件&#xff09;

linux下安装ffmpeg的详细教程、ffmpeg is not installed

1、下载解压 wget http://www.ffmpeg.org/releases/ffmpeg-6.0.tar.gz tar -zxvf ffmpeg-6.0.tar.gz 2、 进入解压后目录,输入如下命令/usr/local/ffmpeg为自己指定的安装目录 cd ffmpeg-6.0 ./configure --prefix/usr/local/ffmpeg make sudo make install 3、配置变量 v…

在Windows下自己从源码编译Python3.10.13成安装包

文章目录 &#xff08;一&#xff09;Python 3.10 的生命周期&#xff08;一&#xff09;下载源码&#xff08;二&#xff09;准备环境&#xff08;三&#xff09;编译&#xff08;3.1&#xff09;解压源码到目录&#xff08;3.2&#xff09;下载依赖&#xff08;PCBuild&#…

推荐一款AI写作大师、问答、绘画工具-「智元兔 AI」

在当今技术飞速发展的时代&#xff0c;人工智能&#xff08;Artificial Intelligence&#xff0c;简称AI&#xff09;的应用已经深入到各个领域。其中&#xff0c;AI写作大师、问答、绘画工具是备受关注和追捧的热门应用之一。在众多的选择中&#xff0c;有一款笔者在使用过程中…

分享一下做一个电商小程序可以实现什么功能

电商小程序是一种基于微信小程序平台的电子商务应用&#xff0c;它可以帮助商家展示商品信息、提供在线支付、订单管理等功能&#xff0c;从而吸引更多的用户进行消费。本文将介绍电商小程序可以实现的一些主要功能&#xff0c;以帮助读者了解其优势和应用场景。 商品展示与搜索…

AWS SAP-C02教程3--网络资源

架构设计中网络也是少不了的一个环节,而AWS有自身的网络结构和网络产品。本章中将带你看看AWS中不同网络产品,以及计算资源、存储资源等产品在网络架构中处于哪个位置,如何才能让它们与互联网互通、与其它产品互通。下图视图将SAP涉及到网络相关组件在一张图表示出来,图中可…

【LeetCode:201. 数字范围按位与 | 位运算】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

【藏经阁一起读(71)】读《阿里云 ClickHouse 企业版技术白皮书》

【藏经阁一起读&#xff08;71&#xff09;】读《阿里云 ClickHouse 企业版技术白皮书》 作者&#xff1a; Tom Schreiber 凤豪 卫寻 魏庄 本书由 ClickHouse 资深技术专家和产品联合撰写&#xff0c;全面介绍了ClickHouse企业版的云原生存算分离整体架构&#xff0c;详细介绍 …

HT for Web (Hightopo) 使用心得(3)- 吸附与锚点

吸附与锚点是 HT for Web 中两个比较重要的概念。这两个概念在执行交互和动画时会经常被用到。 吸附&#xff0c;顾名思义&#xff0c;是一个节点吸附到另一个节点上。就像船底的贝类一样&#xff0c;通过吸附到船身&#xff0c;在船移动的时候自己也会跟着移动&#xff1b;而…

Node.js 新特性 SEA/单文件可执行应用尝鲜

#1 关于 SEA 单文件可执行应用&#xff08;SEA&#xff0c;Singe Executable Applications&#xff09;&#xff0c;是 Node.js 新版本的特性&#xff0c;最初在 v19.7.0、v18.16.0 加入&#xff0c;并在 v20.x 得到扩展。而上个月发布的全家桶 Bun.js&#xff0c;就自带了 SEA…