JVM-基础知识

news2024/11/28 23:37:49

JVM基础知识

JVM结构图

简图
详细图

字节码文件

Java虚拟机不和包括Java在内的任何语言绑定,它只与字节码文件这种特定的二进制文件格式所关联.
Class文件结构不仅仅是JVM的执行入口,更是Java生态圈的基础和核心.

字节码文件内容是什么

字节码是一种二进制的类文件,他的内容是JVM指令,而不像C,C++经由编译器直接生成机器码(JIT后面进行了优化).

class文件编译器

分为前端编译器 就是javac(ecj,eclipse的增量编译器)编译器,他把咱们写的Java代码编译为字节码文件,还有后端的编译器就是JIT,运行时编译,能把字节码文件的执行命令再编译为native的本地执行代码,让运行效率更高(这也是Java说自己的运行效率基本等同于C语言的底气所在) 后面还有个aot提前编译

javac前端编译器的编译步骤

词法解析->语法解析->语义解析->生成字节码

哪些类型对应有class对象
  • class: 类对象都算,包括各种的内部类
  • interface: 接口
  • []: 数组
  • enum: 枚举
  • annotation: 注解
  • primitive type: 基本数据类型
  • void

字节码指令

是由一个字节长度的,代表着某种特定操作含义的操作码(opcode),以及跟随其后的零至多个代表此操作所需参数的操作数(operand)所构成.虚拟机中的许多指令并不包含操作数,只有一个操作码

字节码趣味题目

class文件结构

结构概述
  • 魔数
  • 每个class文件开头的4个字节的无符号整数称为魔数
  • 他的唯一作用是确定这个文件是否为一个能被虚拟机接受的有效合法的Class文件(魔数就是Class文件的标识符)
  • 魔数值固定为0xCAFFBABE不会改变
  • 之所以用魔数不用扩展名是出于安全方面的考虑(因为扩展名可以随意的更改)
  • Class文件版本
  • 排列在magic后的第5个和第6个字节所代表的含义就是编译的副版本号minor_version,而第7个和第8个字节就是编译的主版本号major_version
  • 验证字节码文件的主版本号和次版本号同样也是格式验证的任务之一,因为如果是高版本的JDK编译的字节码文件,自然不能在低版本的JVM中运行,否则JVM会抛出java.lang.UnsupportedClassVersionError异常
  • 常量池(一共是有21项,(其实大小是22,0表示不引用常量池))
  • constant_pool_count (常量池计数器):constant_pool_count的值等于常量池表中的成员数加1。常量池表的索引值只有在大于0且小于constant_pool_count时才会认为是有效的,对于long和 double类型有例外情况。
  • constant_pool [](常量池):constant_pool是一种表结构,以 1 ~ constant_pool_count - 1为索引。它包含class文件结构及其子结构中引用的所有字符串常量、类或接口名、字段名和其他常量。常量池中的每一项都具备相同的特征——第1个字节作为类型标记,用于确定该项的格式,这个字节称为tag byte (标记字节、标签字节)
  • 访问标识(或者说是标志)
  • 常量池后面就是访问标志,用两个字节来表示,其标识了类或者接口的访问信息,比如:该Class文件是类还是接口,是否被定义成public,是否是abstract,如果是类,是否被声明成final等等。
  • 类索引,父类索引,接口索引集合
  • 访问标志后的两个字节就是类索引;
  • 类索引后的两个字节就是父类索引;
  • 父类索引后的两个字节则是接口索引计数器。
  • 通过这三项,就可以确定了这个类的继承关系了。
  • 字段表集合(字段表用来描述类或者接口中声明的变量。这里的字段包含了类级别变量以及实例变量,但是不包括方法内部声明的局部变量)
  • fields_count (字段计数器): fields_count的值表示当前class文件fields表的成员个数。fields表中每个成员都是一个field_info结构,用于表示该类或接口所声明的类字段或者实例字段。
  • fields [](字段表): fields表中的每个成员都必须是一个fields_info结构的数据项,用 于表示当前类或接口中某个字段的完整描述。fields表描述当前类或接口声明的所有字段,但不包括从父类或父接口继承的那些字段。
  • 方法表集合(指向常量池索引集合,它完整描述了每个方法的签名,如果这个方法不是抽象的或者不是native的,那么字节码中会体现出来。)
  • methods_count (方法计数器):methods_count的值表示当前class文件methods表的成员个数。methods 表中每个成员都是一个method_info结构。
  • methods [](方法表):methods表中的每个成员都必须是一个method_info结构,用于表示当前类或接口中某个方法的完整描述。如果某个method_info结构的access_ flags项既没有设置 ACC_NATIVE 标志也没有设置ACC_ABSTRACT标志,那么该 结构中也应包含实现这个方法所用的Java虚拟机指令。
  • method_info 结构可以表示类和接口中定义的所有方法,包括实例方法、类方法、 实例初始化方法和类或接口初始化方法。methods表只描述当前类或接口中声明的方法,不包括从父类或父接口继承的方法。
  • 属性表集合(不同值的集合,它提供了额外的关于这个类的信息,包括任何带有RetentionPolicy.CLASS 或者RetentionPolicy.RUNTIME的注解)
  • attributes_count (属性计数器):attributes_count的值表示当前class文件属性表的成员个数。属性表中每一项都是一个attribute_info结构。
  • attributes [](属性表):属性表的每个项的值必须是attribute_info结构

class结构图标示意

访问标识表
标志名称标志值含义
ACC_PUBLIC0x0001是否为public类型
ACC_FINAL0x0010是否被声明为final,只有类可以设置
ACC_SUPER0x0020是否允许使用invokespecial字节码指令的新语义,jdk1.0.2之后编译出来的类这个标志默认为真
ACC_INTERFACE0x0200标志这个一个接口
ACC_ABSTRACT0x0400是否为abstract类型,对于接口和抽象类来说,此标志值为真,其他的为假
ACC_SYNTHETIC0x1000标志这个类并非由用户代码产生
ACC_ANNOTATION0x2000标志这是一个注解
ACC_ENUMx4000标志这是一个枚举
字段表访问标志

字段表访问标志

方法表访问标志

方法表访问标志

方法表结构

方法表结构

类的加载过程

类的加载过程

Loading(装载)阶段

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

类模板对象就是Java类在jvm当中的一个快照,jvm将从字节码文件中解析出的常量池,类字段,类方法等信息存储到类模板中,这样jvn在运行期间便能通过类模板获取java类中的任意信息,能够对Java的类成员变量遍历,也能调用方法.
反射的机制就是基于这一基础

jdk1.8之前存储在永久代 1.8以后存储在元空间

二进制流的获取方式
  • 通过文件系统读入class扩展名文件
  • 读入jar,war,zip等归档数据包
  • 数据库中读取类的二进制数据
  • 通过http请求远程的信息
  • 运行时直接生成一段class的二进制信息
数组类的加载

它比较特殊,因为数组类本身并不是由类加载器去创建的,而是由jvm在运行时根据需要而直接创建的,但是数组的元素类型仍然需要依靠类加载器去创建,过程如下:

  • 如果数组的元素类型是引用类型,那么就遵循定义的加载过程递归加载和创建数组的元素类型
  • jvm使用指定的元素类型和数组纬度来创建新的数组类
  • 如果数组类的元素类型是引用类型,数组类的可访问性就由数组元素的可访问性决定,否则数组的可访问性将被缺省定义为public

Linking(链接)阶段

  • 验证(Verify,保字节码是合法合理并且符合规范的)
  • 目的在于确保Class文件的字节流中包含信息符合当前虚拟机要求,保证被加载类的正确性,不会危害虚拟机自身安全。
  • 主要包括四种验证,文件格式验证,元数据验证,字节码验证,符号引用验证。
  • 准备(Prepare):
  • 为类的静态变量分配内存,并将其初始化为默认值.
  • 这里不包含用final修饰的static,因为final在编译的时候就会分配了,准备阶段会显式初始化;
  • 这里不会为实例变量分配初始化,类变量会分配在方法区中,而实例变量是会随着对象一起分配到Java堆中。

Java并不支持boolean类型,对于boolean类型,内部实现是int,由于int的默认值是0,所以boolean的默认值就是false

解析(Resolve)阶段

  • 将常量池内的符号引用转换为直接引用的过程。
  • 事实上,解析操作往往会伴随着JVM在执行完初始化之后再执行,符号引用就是一组符号来描述所引用的目标。符号引用的字面量形式明确定义在《java虚拟机规范》的Class文件格式中。在解析阶段,jvm根据字符串的内容找到内存区域中相应的地址,然后把符号引用替换成直接指向目标的指针、句柄、偏移量等,这些直接指向目标的指针、句柄、偏移量就被成为直接引用。
  • 解析动作主要针对类或接口、字段、类方法、接口方法、方法类型等。对应常量池中的CONSTANT_Class_info、CONSTANT_Fieldref_info、CONSTANT_Methodref_info等。
设置栈的大小

现在默认是1Mb大小(不宜设置的过大),用**-Xss size(即 -XX:ThreadStackSize)**来设置,一般默认为512-1024k,取决于操作系统,栈的大小决定了函数调用的最大可达深度

初始化阶段

简单来说就是给类的静态变量赋予正确的初始值

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

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

相关文章

OpenAI竞对再被谷歌加注!4.5亿美元新融资到位,累计已吸金14.5亿美元

量子位 | 公众号 QbitAI OpenAI之外,第二不差钱的AI初创公司出现了! 研发出ChatGPT最强竞品Claude的Anthropic公司,在谷歌投资之后,再次官宣获得了4.5亿美元C轮融资。 这轮收购之后,Anthropic资金一跃达到14.5亿美元…

CPLEX Studio OPL项目介绍

参考B站视频:cplex入门到精通 1.理解 OPL 项目 CPLEX Studio 处理 OPL 项目文件(.project)、数据文件(.dat)、模型文件 (.mod)、设置文件(.ops)和运行配置(.oplproject)。 文件类型扩展名作用份数说明模型文件.mod模型存储和数据1~n必须数据文件.dat数据存储0~n非…

【代码随想录】刷题Day42

1.01背包问题 问题介绍:有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。 1.二维数组实现思想 1.dp[i][j]的含义:首先…

头羊部落亮相首届校园预制菜展,成为预制菜行业领头羊

由北京工商大学与北京市学校基建后勤管理事务中心共同主办的首届预制菜产业与智慧团餐高质量发展研讨会暨校园食材展(以下简称大会)于2023年5月26-27日在北京工商大学举办。 △首届预制菜产业与智慧团餐高质量发展研讨会在北京工商大学隆重举行 △预制菜…

【Python map()、filter() 和 reduce()】零基础也能轻松掌握的学习路线与参考资料

Python编程中常使用map()、filter()和reduce()函数来实现对数据集的操作,尤其是在处理数据时,这些函数非常有用。在本文中,将介绍这些函数的学习路线和优秀实践,并提供一些参考资料供读者参考。 一、Python map() 函数 Python中…

附录5-黑马头条案例

目录 1 效果 2 组件库vant 2.1 安装 2.2 配置 2.3 项目中的使用 2.3.1 引用 2.3.2 tabbar 底部切换 2.3.3 navbar 顶部标题 2.3.4 van-list 上拉触底更新 2.3.5 van-pull-refresh 下拉更新 2.3.6 v-cell 2.3.7 van-icon 2.3.8 自定义风格 3 保持滚…

做接口测试时遇到接口加密了该如何处理

对明文编码生成信息摘要,以防止被篡改。比如MD5使用的是Hash算法,无论多长的输入,MD5都会输出长度为128bits的一个串。 摘要算法不要秘钥,客户端和服务端采用相同的摘要算法即可针对同一段明文获取一致的密文。 对称加密 对称加…

C语言获取AIX单网卡的多IP地址

环境配置 在AIX上,可以使用smitty tcpip命令给单个网卡配置多个IP别名。操作步骤如下: 选择Further Configuration 选择Network Interfaces 选择 Network Interfaces Selection 选择 Configure Aliases 5.选择Add an IPV4 Network Alias 选择需要配…

Vue3:组合式写法入门

Vue3&#xff1a;组合式写法入门 Date: May 11, 2023 认识Vue3 1. Vue3组合式API体验 通过 Counter 案例 体验Vue3新引入的组合式API <script> export default {data(){return {count:0}},methods:{addCount(){this.count}} } </script><script setup> imp…

超声波都应用在哪些领域中?功率放大器如何放大超声波?

超声波是声波的一部分&#xff0c;它的频率高于20kHz&#xff0c;是无法被人耳听到的声波&#xff0c;超声波与声波有共通之处&#xff0c;即它们都是由物体振动所产生&#xff0c;只能在介质中进行传播。无论是在自然界&#xff0c;还是人们的日常生活之中&#xff0c;超声波都…

Power BI DAX函数

1、聚合函数——由表达式定义的列或表中所有行的&#xff08;标量&#xff09;值&#xff0c;例如计数、求和、平均值、最小值或最大值。 函数说明APPROXIMATEDISTINCTCOUNT在列中返回唯一值的估计计数AVERAGE返回列中所有数字的平均值&#xff08;算术平均值&#xff09;AVER…

基于 Python 和深度学习技术实现的人体姿态识别

人体姿态识别是计算机视觉领域的一个重要应用&#xff0c;它通过识别人体的关键点和关节位置&#xff0c;能够准确地判断人体的姿态和动作。这项技术可以应用在很多领域&#xff0c;比如运动训练、医疗康复、安保监控等&#xff0c;为人们的生活和工作带来了很大的便利和效益。…

Fiddler抓包工具之fiddler设置弱网测试

弱网测试 概念&#xff1a;弱网看字面意思就是网络比较弱&#xff0c;我们通称为信号差&#xff0c;网速慢。 意义&#xff1a;模拟在地铁、隧道、电梯和车库等场景下使用APP &#xff0c;网络会出现延时、中断和超时等情况。 Fiddler弱网测试流程&#xff1a; 一、限速操作…

redis学习记录

前言 1. 什么是Redis&#xff1f;它主要用来什么的&#xff1f; Redis&#xff0c;英文全称是 Remote Dictionary Server&#xff08;远程字典服务&#xff09;&#xff0c;是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xf…

代码里乐观锁与悲观锁

乐观锁与悲观锁区别 synchronized与cas举例 cas算法自旋 乐观锁原理&#xff1a;cas算法自旋 1.cas算法 2.自旋 乐观锁工具类 Atomiclnteger原子类incrementAndGet方法源码解析

React Fiber架构

说到Fiber&#xff0c;不得不说说他的发展史&#xff1a; React15 架构 React16之前的版本比对更新虚拟DOM的过程是采用循环递归方式来实现的&#xff0c;这种比对方式有一个问题&#xff0c;就是一旦任务开始进行就无法中断&#xff0c;如果应用中数组数量庞大&#xff0c;主…

红黑树及插入过程详解

推荐可视化插入、删除节点的二叉树网站&#xff1a;Red/Black Tree Visualization (usfca.edu) 1. 概述 红黑树&#xff08;Red-Black Tree&#xff09;是一种自平衡的二叉搜索树&#xff08;Binary Search Tree&#xff09;。它在普通二叉搜索树的基础上通过引入额外的颜色属…

DragGAN图像生成原理与实现

DragGAN图像生成原理与实现 DragGAN模型是什么呢1. DragGAN背景介绍2. 模型方法2.1 算法原理2.1.1 Motion Supervision2.1.2 点跟踪 3. 实现部署步骤3.1 安装PyTorch3.2 安装 DragGAN3.3 运行 DragGAN Demo3.4 功能介绍 项目地址&#xff1a;https://github.com/Zeqiang-Lai/Dr…

衡量有效的质量保证过程的10个基本指标

作者 | Tania Zhydkova 在开发的世界中&#xff0c;有一个永恒的规则&#xff0c;那就是你无法改进无法衡量的东西。当然&#xff0c;这条规则也适用于质量保证。 所生产软件的阵列呈指数级增长&#xff0c;这意味着保证质量所需的测试覆盖率也在以同样的程度增长。这也导致了…