类文件结构——深入理解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程序设 ...
随机推荐
- MySQL优化之COUNT(*)效率(部分转载与个人亲测)
说到MySQL的COUNT(*)的效率,发现越说越说不清楚,干脆写下来,分享给大家. COUNT(*)与COUNT(COL)网上搜索了下,发现各种说法都有:比如认为COUNT(COL)比COUNT(* ...
- 面试题56 - I. 数组中数字出现的次数
面试题56 - I. 数组中数字出现的次数 一个整型数组 nums 里除两个数字之外,其他数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度是O(n),空间复杂度是O(1). 示例 ...
- curl请求本地域名问题
curl在本地虚拟机上请求本地接口时候,出现域名解析问题,换为ip即可,可用curl_error() 或者curl_errno来调试: vue单个文件在引入时候自己的逻辑js文件一定要放在html后引 ...
- sql注入学习笔记
1.什么是SQL注入 SQL注入就是指web应用程序对用户输入的数据的合法性没有判断,前端传入后端的参数带有数据库查询的语句,攻击者可以构造不同的SQL语句来实现对数据库的操作. 2.SQL注入原理 ...
- iscsi的工作原理与优化(2)
2.1 iSCSI协议模型,iscsi[会话层协议,即应用协议] iSCSI使用TCP/IP协议在不稳定网络上进行可靠的数据传输.iSCSI层和标准SCSI集在协议栈中的位置如图1所示.iSCSI层包 ...
- linux find string in files
http://blog.csdn.net/duguduchong/article/details/7716908 查找目录下的所有文件中是否含有某个字符串 find .|xargs grep -ri ...
- Javascript基础之-var,let和const深入解析(二)
你想在在变量声明之前就使用变量?以后再也别这样做了. 新的声明方式(let,const)较之之前的声明方式(var),还有一个区别,就是新的方式不允许在变量声明之前就使用该变量,但是var是可以得.请 ...
- 是时候实现 SOC 2.0 了
本文讲的是是时候实现 SOC 2.0 了,SOC,安全运营中心,为取得其最佳效果,以及真正最小化网络风险,需要全员就位,让安全成为每个人的责任. 早在几年前,企业就开始创建SOC来集中化威胁与漏洞的监 ...
- Docker学习之搭建MySql容器服务
描述 MySQL 5.6 SQL数据库服务器Docker镜像,此容器映像包含用于OpenShift的MySQL 5.6 SQL数据库服务器和一般用法.用户可以选择RHEL和基于CentOS的图像.然后 ...
- webpack4.x下babel的安装、配置及使用
前言 目前,ES6(ES2015)这样的语法已经得到很大规模的应用,它具有更加简洁.功能更加强大的特点,实际项目中很可能会使用采用了ES6语法的模块,但浏览器对于ES6语法的支持并不完善.为了实现兼容 ...