深入理解jvm-2Edition-类文件结构
概述:
规范而独立的类文件结构以及只与类文件关联的虚拟机为Java实现了平台无关性,甚至还带来了一些语言无关性。
只要将源代码编译为Class文件规定的格式,JVM就可以执行。
JVM的指令描述能力比Java更强,这使得JVM可以执行不同于Java语言特性的语言。
1、Class文件整体结构
以字节为基本单位,无分隔符,大端(低地址存高位)。
无论是数量还是顺序都严格规定了(确定性)。
两种数据类型:无符号数和表
1、无符号数:u1、u2、、u4、u8分别代表1、2、4、8字节的无符号数。可用来描述数字、索引引用、数量值或UTF-8字符串。
2、表:由多个无符号数或者表组成。整个Class文件可看作是一张表。
3、数量不确定时,必须有一个前置的数量说明。
2、Magic Number和版本号
魔数:标识该文件是一个Class文件。
版本号:Minor Version和Major Version,标识该Class文件的版本(能执行该Class文件的JVM最低版本)。
Java版本号从45开始,每一个JDK大版本发布,主版本号加1。
3、常量池
可以理解为Class文件中的资源仓库,通常是Class文件中最占空间的一部分。被其他部分所引用,常量池元素之间也存在相互引用。就如同搭积木一样。
(只有)常量池计数从1开始,0留出是为了表示不引用任何常量池元素的情况。
两大类型常量:
1、字面量Literal:基本类型和字符串。
2、符号引用(引用其他常量池元素)Symbolic Reference:
1、类和接口的全限定名;
2、字段的名称和描述符;
3、方法的名称和描述符。
Java编译过程没有链接步骤,Class文件没有保存各个方法、字段在内存中的布局信息,要依靠虚拟机加载Class文件的时候进行动态链接。
虚拟机运行时,需要从常量池中获得对应的符号引用,再在类创建或运行时解析、翻译到具体的内存地址之中。
4、访问标志
通过标志位用两个字节表示。
5、类索引、父类索引和接口索引集合
这三个索引用于确定类的继承关系。
类索引、父类索引和接口索引集合按顺序排列在访问标志之后,其中类索引和父类索引各用一个u2类型的索引值表示,指向常量池中的一个CONSTANT_Class_info元素。
由于可以实现多个接口,因此,要增加一个接口计数器,随后紧接着接口索引集合。
接口索引同样用一个u2类型的索引值表示,指向常量池中的一个CONSTANT_Class_info元素。
6、字段表集合
name_index引用常量池中的元素,为字段的简单名。
descriptor_index引用常量池中的元素,为字段的描述符(包括数据类型)。
描述符用于描述字段的数据类型,方法的参数列表(包括数量、类型、顺序)和返回值。
由于字段(方法)名已经有单独的属性描述了,因此描述符里不再包括。
描述方法时,按照先参数列表,后返回值的顺序。参数列表严格按照参数顺序放在“()”之内。void 对应的描述符为V。
描述符示例:
F: int i; D: I
F: java.lang.String[][] S; D: [[Ljava/lang/String
M: void inc(); D: ()V
M: double add(double x, double y); D: (DD)D
M: int add(int[] array); D: ([I)I
M: int indexOf(char[] source, int sourceOffset, int sourceCount, char[] target, int targetOffset, int targetCount, int fromIndex);
D: ([CII[CIII)I
字段表不会包含继承而来的字段,但可能包含Java代码中没有的字段(如内部类中包含外部类的引用)。
7、方法表集合
方法表的结构和字段表一样,只是每个属性的具体内容有所变化(如访问字段变了)。
如果子类方法表不会包含父类方法,除非子类重写了那个方法。
可能出现代码中没有的方法,如编译器添加的类构造器<cinit>方法和实例构造器<init>方法。
Java中特征签名就是一个方法中各个参数在常量池中的字段符号引用的集合,返回值不包含在特征签名中,因此Java无法通过返回值区分方法重载。
但是在Class文件格式中,特征签名还包括方法返回值和受查异常表,因此只有返回值不同的两个方法也能在Class文件中共存。
编译后的字节码去哪儿了?
在方法属性表集合中的Code属性里面。
8、属性表集合
属性表都有固定的两项
1、u2类型的attribute_name_index,指向常量池中CONSTANT_Utf8_info 型常量的索引,代表属性名。
2、u4类型的attribute_length,表示后面的attribute_info的数量。
1、code属性-方法表
javac编译器编译处理后的字节码指令,一个字节表示一个指令。
并非所有方法都存在Code属性,抽象方法就没有。
exception_table:
2、Exceptions属性-方法表
与Code属性平级的属性,不是exception_table !
3、LineNumberTable属性-Code属性
描述Java源码与字节码偏移量的对应关系,用于调试。
可在编译时加 -g:none 或 -g:lines 参数关闭。
4、LocalVariableTable属性-Code属性
描述栈帧中局部变量表与Java源码中定义的变量之间的关系。
可在编译时加 -g:none 或 -g:vars 参数关闭。
5、SourceFile属性-类文件
记录Class文件对应的源码文件的名称。
可在编译时加 -g:none 或 -g:source 参数关闭。
6、ConstantValue属性-字段表
记录编译时常量的值。
7、InnerClasses 属性
记录内部类与宿主类的关联。
8、Deprecated和Synthetic属性
Deprecated类似于@Deprecated。
Synthetic表示此字段或方法不是Java源码直接生成的。
9、StackMapTable 属性
用于类加载时的类型检查。
10、Signiture属性
用于在擦除法后获取泛型的信息。
11、BootstrapMethods属性
用于保存invokedynamic指令引用的引导方法限定符。
9、字节码指令简介
Java字节码指令和C/C++汇编不太一样,它没有寄存器的概念。而是采用了操作数栈来进行数据的传递和运算。
同时,一个字节序列就是一个指令。因此最多只能有256个指令。因此,不是每种类型数据都有对应的运算指令。。
可以分为:
1、加载和存储指令
2、运算指令
3、类型转换指令
4、对象创建与访问指令
5、操作数栈管理指令
6、控制转移指令
7、方法调用和返回指令
8、异常处理指令
9、同步指令
深入理解jvm-2Edition-类文件结构的更多相关文章
- 深入理解JVM(六)类文件结构
6.1 关于类文件 1.class文件的一次编译,到处运行的跨平台性: 2.JVM不止有跨平台性,还有跨语言性,不管是JRuby还是Groovy写出来的程序,只要编译出符合JVM规范的class文件就 ...
- JVM(4) 类文件结构
一.实现“平台无关性” 字节码(ByteCode)存储格式和虚拟机是实现语言无关性的基础.Java虚拟机不和包括Java在内的任何语言绑定,它只与“Clas”文件这种特定的二进制文件格式所关联,Cla ...
- JVM小结--类文件结构
字节码是构成Java平台无关性的基石.实现语言无关性的基础是虚拟机和字节码存储格式. Java语言中的各种变量.关键字和运算符的语义最终是由多条字节码命令组成,因此字节码命令所能提供的语义描述能力肯定 ...
- 《深入理解Java虚拟机》类文件结构
上节学习回顾 在上一节当中,主要以自己的工作环境简单地介绍了一下自身的一些调优或者说是故障处理经验.所谓百变不离其宗,这个宗就是我们解决问题的思路了. 本节学习重点 在前面几章,我们宏观地了解了虚拟机 ...
- 《深入理解java虚拟机》笔记——简析java类文件结构
一直不太搞得明确jvm究竟是如何进行类载入的,在看资料的过程中迷迷糊糊.在理解类载入之前,首先看看java的类文件结构究竟是如何的,都包含了哪些内容. 最直接的參考当然是官方文档:The Java® ...
- 《深入理解Java虚拟机》-----第6章 类文件结构——Java高级开发必须懂的
代码编译的结果从本地机器码转变为字节码,是存储格式发展的一小步,却是编程语言发展的一大步. 6.1 概述 记得在第一节计算机程序课上我的老师就讲过:“计算机只认识0和1,所以我们写的程序需要经编译器翻 ...
- 深入理解Java虚拟机(类文件结构+类加载机制+字节码执行引擎)
目录 1.类文件结构 1.1 Class类文件结构 1.2 魔数与Class文件的版本 1.3 常量池 1.4 访问标志 1.5 类索引.父索引与接口索引集合 1.6 字段表集合 1.7 方法集合 1 ...
- JVM学习笔记(三):类文件结构
代码编译的结果从本地机器码转变为字节码,是存储格式发展的一小步,却是编程语言发展的一大步. 实现语言无关性的基础是虚拟机和字节码存储格式.Java虚拟机不和包括Java在内的任何语言绑定,只与&quo ...
- jvm 类文件结构学习
本文以代码示例来学习 java 类文件的结构,其中对类文件结构的学习均来自周志明先生所著的 <深入理解 Java 虚拟机>一书,在此表示诚挚的感谢. 代码如下: package com.r ...
- 【搞定Jvm面试】 面试官:谈谈 JVM 类文件结构的认识
类文件结构 一 概述 在 Java 中,JVM 可以理解的代码就叫做字节码(即扩展名为 .class 的文件),它不面向任何特定的处理器,只面向虚拟机.Java 语言通过字节码的方式,在一定程度上解决 ...
随机推荐
- Web自动化之iframe切换
一.如何判断元素是否在iframe中 选中要操作的元素,通过下方的父节点查看是否存在iframe,存在则元素在iframe,需要切换至iframe中进行元素的操作 二.iframe切换方式一 1.方式 ...
- Python小白的数学建模课-B5. 新冠疫情 SEIR模型
传染病的数学模型是数学建模中的典型问题,常见的传染病模型有 SI.SIR.SIRS.SEIR 模型. 考虑存在易感者.暴露者.患病者和康复者四类人群,适用于具有潜伏期.治愈后获得终身免疫的传染病. 本 ...
- kafka、rabbitmq、redis区别,各自适合什么场景?
在应用场景方面 RabbitMQ RabbitMQ遵循AMQP协议,由内在高并发的erlanng语言开发,用在实时的对可靠性要求比较高的消息传递上,适合企业级的消息发送订阅,也是比较受到大家欢迎的. ...
- Kotlin Coroutine(协程): 二、初识协程
@ 目录 前言 一.初识协程 1.runBlocking: 阻塞协程 2.launch: 创建协程 3.Job 4.coroutineScope 5.协程取消 6.协程超时 7.async 并行任务 ...
- Vue3 + Cesium + Typescript 集成搭建的快速启动模板(包含示例数据)
开门见山 项目地址:https://github.com/tanghaojie/vue3-cesium-typescript-start-up-template 好用的话给个star呗,有更新可以第一 ...
- FreeRTOS常用函数
一.任务 任务创建和删除xTaskCreate 任务创建xTaskDelete ...
- Chirp Z-Transform
Chirp Z-Transform 其实不是什么特别难的东西. 用于解决等比数列/类等比数列多点求值. \(b_i=\sum_{j=0}^{n}a_jc^{ij}\) 注意到 \(ij=\binom{ ...
- C语言:进制转化
16进制数4321转10进制:原来方法 =4*16^3+3*16^2+2*16^1+1*16^0 =4*16^3+3*16^2+2*16^1+1 =16*(4*16^2+3*16^1+2)+1 =16 ...
- [刘阳Java]_SpringMVC访问静态资源_第9讲
有些时候我们在使用SpringMVC的时候造成无法访问静态资源文件(如:html,js,css,image等等).其主要的原因出在web.xml文件我们设置SpringMVC前端控制器的映射路径 &l ...
- CF1330B题解
题意: 给定一个长为 \(n\) 序列 \(a\) ,问是否能分成两个排列,并输出方案 (排列:从 \(1-n\) 中选取不同的 \(n\) 个元素组成的序列) 思路: 观察数据范围可以猜出,这题 \ ...