类文件结构——深入理解Java虚拟机 笔记三
在之前的笔记中记录过,Java程序变成可执行文件的步骤是:源代码——>经过编译变成class文件——>经过JVM虚拟机变成可执行的二进制文件。因此,为了对JVM执行程序的过程有一个好的了解,我们需要先明白class文件到底是什么东西,它里面有那些信息以及如何存储的。
Class类文件结构
Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑排列在Class文件中。当遇到需要占用超过8位字节的数据项时,则会按照高位在前的方式分割成若干个8位字节进行存储。
Class文件格式采用一种类似于C语言结构体的伪结构来存储,这种伪结构中只有两种数据类型:无符号数和表。
无符号数是基本的数据类型,以u1,u2,u4,u8分别表示1个字节、2个字节、4个字节、8个字节的无符号数,无符号数可以用来描述数字、索引引用、数量值或者按照UTF-8编码构成的字符串值。
表是由多个无符号数或者其他表作为数据项构成的复合数据结构,所有表习惯性地以_info结尾。
我们先来看一下Class文件的格式,然后对这些数据一一进行讲解。

魔数和Class文件的版本
每个Class文件的头四个字节称为魔数,作用是来表示该文件是一个可以被虚拟机接受的Class文件。其作用类似于扩展名,但扩展名易更改,而魔数来进行类型判别比较安全。
紧接着的四个字节存储的是Class文件的版本号。第5、6字节为次版本号,第7、8字节为主版本号。

常量池
版本号之后的就是常量池。常量池是Class文件结构中与其他项目关联最多的数据类型,也是占用Class文件空间最大的数据项目之一。
常量池中主要存放两大类常量,字面量和符号引用。字面量比较接近于Java语言的常量概念,比如文本字符串、被声明为final的常量值等等而符号引用属于编译原理方面的概念,包括了下面三类常量:1、类和接口的全限定名 2、字段的名称和描述符 3、方法的名称和描述符
Java代码进行编译的时候,没有C那样用"链接"这一步骤,而是在虚拟机加载Class文件的时候进行动态链接。也就是Class文件不会保存各个方法和字段的最终内存布局信息,因此这些字段和方法的符号引用不经过转换的话是无法被虚拟机使用的。当虚拟机运行的时候,需要从常量池获得对应的符号引用,再在类创建或运行的时候解析并翻译到具体内存地址中 ??
对这些一一列举也没有什么意义,如果需要某一项的内容,可以单独查找。本章我认为更关键的是对Class文件怎么生成的,怎么运作的理解。
在常量池中,记载了各种常量(包括系统执行时内部需要的)、方法表(用来记录该类的所有方法)、属性表等。他们的运作方法大同小异:通过已经定义的常量(包括字符串常量、方法名之类的信息)来填充对应的表信息,比如方法表中,我们需要得到方法名、返回值、参数等等信息,这些信息都存储在常量池中,只需要引用到对应位置即可表示。而方法表中更为关键的信息就是Code属性了,Code属性表示了该方法的执行过程。
先看一下Code属性表的内容:

里面像attribute_name_index之类都是索引,指向常量池中的一个字符串来表示对应的数据常量。关键的地方是code_length和后面的code,他们用来存储Java源代码编译后生成的字节码指令。code_length代码字节码长度,code用于存储字节码指令的一系列字节流,每一个指令都是一个u1类型的单字节。,当虚拟机读到对应字节码的字节后,他会查询出是什么指令并执行。

通过指令的分析,我们可以看到,通过字节码我们可以实现利用常量池中的数据信息,来分析运行结果并执行的。
在这个字节码中,它执行的数据交换、方法调用都是基于操作栈进行的,比如2A将对象移动到栈顶,B7是以栈顶对象为接受者,他们都是对一个栈进行的操作,但又有像invokespecial这样带参数的指令,这就与单纯使用堆栈进行操作不相符,因此另一个问题是JVM如何堆字节码执行。
类文件结构——深入理解Java虚拟机 笔记三的更多相关文章
- 深入理解Java虚拟机第三版,总结笔记【随时更新】
最近一直在看<深入理解Java虚拟机>第三版,无意中发现了第三版是最近才发行的,听说讲解的JDK版本升级,新增了近50%的内容. 这种神书,看懂了,看进去了,真的看的很快,并没有想象中的晦 ...
- Java内存区域与内存溢出异常——深入理解Java虚拟机 笔记一
Java内存区域 对比与C和C++,Java程序员不需要时时刻刻在意对象的创建和删除过程造成的内存溢出.内存泄露等问题,Java虚拟机很好地帮助我们解决了内存管理的问题,但深入理解Java内存区域,有 ...
- 深入理解Java虚拟机笔记
1. Java虚拟机所管理的内存 2. 对象创建过程 3. GC收集 4. HotSpot算法的实现 5. 垃圾收集器 6. 对象分配内存与回收细节 7. 类文件结构 8. 虚拟机类加载机制 9.类加 ...
- 深入理解java虚拟机笔记Chapter12
(本节笔记的线程收录在线程/并发相关的笔记中,未在此处提及) Java内存模型 Java 内存模型主要由以下三部分构成:1 个主内存.n 个线程.n 个工作内存(与线程一一对应) 主内存与工作内存 J ...
- 深入理解java虚拟机笔记Chapter7
虚拟机类的加载机制 概述 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类的加载机制. 类加载的时机 J ...
- 深入理解java虚拟机(三)对象回收判断算法以及死亡过程
在堆里面存放着Java几乎所有的对象实例,垃圾收集器要进行垃圾回收,要做的第一步便是找出那些对象是需要回收的. 怎么判断对象是否需要回收? 常用的方法有两种. 1.引用计数算法.为每一个对象添加一个引 ...
- 深入理解Java虚拟机笔记——虚拟机类加载机制
目录 概述 动态加载和动态连接 类加载的时机 类的生命周期 被动引用 例子一(调用子类继承父类的字段) 例子二(数组) 例子三(静态常量) 类加载的过程 加载 验证 准备 解析 符号引用 直接引用 初 ...
- 深入理解java虚拟机笔记Chapter8
运行时栈帧结构 栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构,它是虚拟机运行时数据区中的虚拟机栈(Virtual Machine Stack)的栈元素.栈帧存储了方法 ...
- 深入理解java虚拟机笔记之一
Java的技术体系主要有支撑java程序运行的虚拟机,提供各开发领域接口支持Java API,java编程语言及许多第三方java框架( 如Spring,Structs等)构成. 可以把Java程序设 ...
随机推荐
- Linux必须会的命令---也是以前记录的,ctrl+z fg 啥的 jobs 比较实用
fg.bg.jobs.&.ctrl + z都是跟系统任务有关的,虽然现在基本上不怎么需要用到这些命令,但学会了也是很实用的 一.& 最经常被用到 这个用在一个命令的最后,可以把这个命令 ...
- ES6中对数组的扩展
hello,大家好,我又来了. 前面讲了字符串和数值的扩展,今天要讲的是:数组的扩展.不知道大家能否跟得上这个节奏,你们在阅读中对讲解有存在疑惑,记得留言提出来,要真正地理解,否则白白 ...
- 模拟HTTP请求调用controller
原文参考本人的简书:https://www.jianshu.com/p/0221edbe1598 MockMvc实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller调用,这样 ...
- GOLANG 闭包和普通函数的区别
闭包和匿名函数是一回事 闭包使用完毕之后不会自动释放,值依然存在 普通函数调用完毕后,值会自动释放
- 基于NFS共享存储实现KVM虚拟机动态迁移
基于NFS共享存储实现KVM虚拟机动态迁移 一:配置环境 二:安装相关的依赖包 三:实现NFS共享存储 四:KVM机配置相同的步骤 五:安装KVM01安装虚拟机 六:实现迁移 实验初始配置:所有主机 ...
- 内蒙古特检院利用物联网/RFID技术提高电梯检测水平
随着电梯检验工作信息化进程的进一步深入,内蒙古特检院从检验工作中寻找新方法.新手段,为检验员新引入电梯检验手持终端设备,力求提高电梯检验水平,将"电梯安全惠民工程"落到实处. 电梯 ...
- MySQL UDF Dynamic Library Exploit in *nix
/* } 本文转hackfreer51CTO博客,原文链接:http://blog.51cto.com/pnig0s1992/575448,如需转载请自行联系原作者
- Clickhosue 强大的函数,argMin() 和argMax()函数
说实话,我喜欢Clickhouse 的函数,简单操作,功能强大.今天需要给大家介绍两个函数,argMin(),argMax() 1.argMax():计算 ‘arg’ 最大值 ‘val’ 价值. 如果 ...
- Process Synchronization-Example 2
问题描述 理发店有一位理发师,一把理发椅和N把供等候的顾客坐的椅子. 如果没有顾客,理发师在理发椅上睡觉: 当有一个顾客到来时,他必须先唤醒理发师: 如果顾客来时理发师正在理发,如果有空椅子,坐下等待 ...
- gVim配置文件分享
前言 直接可以把这个配置覆盖掉现在安装目录Vim底下的"_vimrc"文件 效果图 Code: set number set tabstop=4 set softtabstop=4 ...