要点提炼| 理解JVM之类文件结构

之前还在美团实习的时候,当时读《深入理解Java虚拟机》由于时间原因只总结了几个章节,现在把余下的几个章节补充上,发表顺序有些混乱,章节主线详见文章汇总|学习Android的一点一滴

本篇将介绍Class文件结构中的各个组成部分,以及每个部分的定义、数据结构和使用,有利于进一步了解虚拟机执行引擎。

  • 概述
  • 类文件结构
  • 字节码指令

1.概述

运行在各种不同平台上的虚拟机通过载入和执行同一种平台无关的字节码来实现了程序的“一次编写,到处运行”。可见字节码是构成平台无关性的基石。

Java虚拟机不和Java等任何语言绑定,只和存储字节码的Class文件这种特定的二进制文件格式关联,且并不关心Class的来源是何种语言,也体现了Java虚拟机的语言无关性


2.类文件结构

  • Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件之中,中间无任何分隔符,当遇到需要占用8位字节以上空间的数据项时,会按照高位在前的方式分割成若干个8位字节进行存储。
  • Class文件格式采用一种类似于C语言结构体的伪结构来存储数据,包含两种数据类型:
    • 无符号数:属于基本数据类型;以u1、u2、u4、u8来分别代表1个字节、2个字节、4个字节和8个字节的无符号数;可用于描述数字、索引引用、数量值或按照UTF-8 编码构成的字符串值。
    • :由多个无符号数或其他表作为数据项构成的复合数据类型;常以“_info”结尾;可用于描述有层次关系的复合结构的数据。
  • 整个Class文件本质上就是一张表,所包含的数据项如图:

接下来依次介绍表中各个数据项的具体含义。

a. 魔数

  • 魔数(Magic Number):每个Class文件的头4个字节
  • 作用:判断该文件是否为一个能被虚拟机接受的Class文件

b.版本号

  • 版本号:包含主版本号和一系列次版本号
    • 次版本号(Minor Version):第5和第6个字节
    • 主版本号(Major Version):第7和第8个字节
  • 作用:判断该文件是否在虚拟机处理的有效范围内

c.常量池

  • 常量池:使用一个前置的容量计数器(constant_pool_count)加上若干个连续的常量项(constant_pool)来描述
    • 容量计数器:从1开始,目的是满足后面某些指向常量池的索引值的数据在特定情况下需要表达“不引用任何一个常量池项目”的含义,这时可以把索引值置为0来表示
    • 常量项:如constant_pool_count=2表示常量池中有1个常量项
  • 特点:是Class文件的资源仓库、是Class文件结构中与其他项目关联最多的数据类型、是占用Class文件空间最大的数据项目之一、是在Class文件中第一个出现的表类型数据项目
  • 存放内容:两大类常量
    • 字面量(Literal):指Java语言层面的常量概念,如文本字符串、声明为final的常量值等
    • 符号引用(Symbolic References):指编译原理方面的概念,包含类和接口的全限定名(Fully Qualified Name)、字段的名称和描述符(Descriptor)、方法的名称和描述符

Java代码进行Javac编译的过程同虚拟机加载Class文件的过程是动态连接的,因此在Class文件中不会保存各个方法、字段的最终内存布局信息,这就需要虚拟机在运行时从常量池获得对应的符号引用,再在类创建时或运行时解析、翻译到具体的内存地址之中。

d.访问标志

  • 访问标志(access_flags):常量池结束后两个字节
  • 作用:识别一些类或者接口层次的访问信息,包括该Class是类还是接口、是否定义为public类型、是否定义为abstract类型、若是类是否被声明为final等。具体的标志位以及含义见图:

e.类索引、父类索引与接口索引集合

  • 类索引(this_class)和父类索引(super_class)都是一个u2类型的数据、接口索引集合(interfaces)是一组u2类型的数据的集合
  • 作用: 通过这三项数据来确定这个类的继承关系,具体的
    • 类索引:确定这个类的全限定名
    • 父类索引:确定这个类的父类的全限定名
    • 接口索引集合:描述这个类所实现的接口,并按照implements语句后的接口顺序从左到右排列在接口索引集合中
      • 接口索引集合的入口第一项u2类型数据为接口计数器(interfaces_count),从0计数,如nterfaces_count=2表示该类实现了两个接口

类全限定名:把类全名中的“.”都替换成“/”,为了使连续的多个全限定名之间不产生混淆,在使用时最后一般会加入一个“;”表示全限定名结束

f.字段表集合

  • 字段表(field_info):用于描述接口或者类中声明的变量
  • 格式如图
    • access_flags:存放字段的修饰符,具体的标志位以及含义见图:
    • name_index:存放字段的简单名称,即没有类型和参数修饰的字段名称
    • descriptor_index:存放字段和方法的描述符,包括字段的数据类型、方法的参数列表(包括数量、类型以及顺序)和返回值,具体的标志位以及含义见图:
    • attribute_info:属性表见后

g.方法表集合

  • 方法表(methods_info):用于描述接口或者类中声明的方法
  • 格式如图,可见和描述字段的方式非常类似,仅在访问标志和属性表集合的可选项中有所区别。

h.属性表集合

  • 属性表(attribute_info):用于描述某些场景专有的信息,在字段表、方法表等都携带自己的属性表集合
  • 种类:


  • 结构:属性名需要从常量池中引用一个CONSTANT_Utf8_info类型的常量来表示,属性值是自定义的、需要通过一个u4的长度属性说明属性值所占用的位数

举例class文件结构解析class文件属性表解析


3.字节码指令

  • 构成:由一个字节长度的表示某种特定操作含义的操作(操作码、Opcode)和零至多个代表此操作所需的参数(操作数、Operands)构成
  • 特点:非完全独立,即并非每种数据类型和每一种操作都有对应的指令,有些单独的指令可以在必要的时候用来将一些不支持的类型转换为可被支持的类型
  • 分类:将字节码操作按用途大致分为9类
    • 加载和存储指令:用于将数据在栈帧中的局部变量表和操作数栈之间来回传输
    • 运算指令:用于对两个操作数栈上的值进行某种特定运算,并把结果重新存入到操作栈顶
    • 类型转换指令 :用于实现用户代码中的显式类型转换操作,或者用于处理字节码指令集中数据类型相关指令无法与数据类型一一对应的问题
    • 对象创建与访问指令:用于对象创建,并通过对象访问指令获取对象实例或者数组实例中的字段或者数组元素
    • 操作数栈管理指令:用于直接操作操作数栈
    • 控制转移指令:用于从指定的位置有条件或无条件地进行指令
    • 方法调用和返回指令:用于方法的调用,并根据返回值的类型去返回
    • 异常处理指令:用于检测到异常状况时自动抛出异常
    • 同步指令:用于方法内部一段指令序列的同步

具体指令见Java虚拟机字节码指令简介


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容