2018-05-11

《深入理解Java虚拟机:JVM高级特性与最佳实践(第二版》读书笔记与常见面试题总结本节常见面试题(推荐带着问题阅读,问题答案在文中都有提到):简单介绍一下Class类文件结构(常量池主要存放的是那两大常量?Class文件的继承关系是如何确定的?字段表、方法表、属性表主要包含那些信息?)1 概述计算机虽然只能识别0和1,但是越来越多的程序语言选择了与操作系统和机器指令集无关无关的、平台中立的格式作为程序编译后的存储格式。Java虚拟机不和包括Java在内的任何语言绑定,只与 "Class文件" 这种特定的二进制文件所关联,Class文件中包含了Java虚拟机指令集合符号表以及若干其它辅助信息。Java虚拟机作为一个通用的、机器无关的执行平台,任何其他语言都可以将其作为语言的产品交付媒介。2 Class类文件结构Class文件是一组以8位字节为基础的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件之中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部是程序运行的必要数据,没有空隙存在。当遇到需要占用8位字节以上空间的数据项时,则会按照高位在前的方式分割成若干个8位字节进行存储。Class文件格式采用一种类似于C语言结构体的伪结构来存储数,这种伪结构有两种数据类型:无符号数和表。这里需要重复提一下,Class文件结构不像XML等描述语言,由于它没有任何分割符号,所以无论是数量甚至于数据存储的字节序这样的细节都被严格限定,哪个字节代表什么含义,长度是多少,先后顺序如何,都不允许改变。2.1 魔数与Class文件版本每个Class文件的头四个字节称为魔数(Magic Number),它的唯一作用是确定这个文件是否为一个能被虚拟机接收的Class文件。紧接着魔数的四个字节存储的是Class文件的版本号:第五和第六是次版本号,第七和第八是主版本号。2.2 常量池紧接着主次版本号之后的是常量池入口,常量池可以理解为Class文件之中的资源仓库,它是Class文件结构中与其他项目关联最多的数据类型,也是占用Class文件空间最大的数据项目之一,同时它还是在Class文件中第一个出现的表类型数据项目。常量池主要存放两大常量:字面量和符号引用。字面量比较接近于java语言层面的的常量概念,如文本字符串、声明为final的常量值等。而符号引用则属于编译原理方面的概念。包括下面三类常量:类和接口的全限定名字段的名称和描述符方法的名称和描述符2.3访问标志在常量池结束之后,紧接着的两个字节代表访问标志,这个标志用于识别一些类或者接口层次的访问信息,包括:这个Class是类还是接口,是否为public或者abstract类型,如果是类的话是否声明为final等等。具体标志位及标志的含义如下图所示:2.4 类索引、父类索引与接口索引集合类索引、父类索引与接口索引集合都按顺序排列在访问标志之后,Class文件由这三项数据来确定这个类的继承关系。类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名,由于java语言的单继承,所以父类索引只有一个,除了java.lang.Object之外,所有的java类都有父类,因此除了java.lang.Object外,所有java类的父类索引都不为0。接口索引集合用来描述这个类实现了那些接口,这些被实现的接口将按implents(如果这个类本身是接口的话则是extends)后的接口顺序从左到右排列在接口索引集合中。2.5 字段表集合字段表(field info)用于描述接口或类中声明的变量。字段包括类级变量以及实例变量,但不包括在方法内部声明的局部变量。我们可以想一想在java中描述一个字段可以包含什么信息呢?字段的作用域(public ,private,protected修饰符),是实例变量还是类变量(static修饰符)、可变性(final)、并发可见性(volatile修饰符,是否强制从主内存读写)、可否被序列化(transient修饰符)、字段数据类型、字段名称。上述这些信息中,各个修饰符都是布尔值,要么有某个修饰符,要么没有,很适合使用标志位来表示。而字段叫什么名字、字段被定义为什么数据类型这些都是无法固定的,只能引用常量池中常量来描述。2.6方法表集合Class文件存储格式中对方法的描述与对字段的描述几乎采用了完全一致的方式。方法标的结构如同字段表一样,依次包括了访问标志、名称索引、描述符索引、属性表集合几项。在这里稍微提一下,因为volatile修饰符和transient修饰符不可以修饰方法,所以方法表的访问标志中没有这两个对应的标志,但是增加了synchronized、native、abstract等关键字修饰方法,所以也就多了这些关键字对应的标志。2.7 属性表结合在Class文件,字段表,方法表中都可以携带自己的属性表集合,以用于描述某些场景专有的信息。与Class文件中其它的数据项目要求的顺序、长 度和内容不同,属性表集合的限制稍微宽松一些,不再要求各个属性表具有严格的顺序,并且只要不与已有的属性名重复,任何人实现的编译器都可以向属性表中写 入自己定义的属性信息,Java虚拟机运行时会忽略掉它不认识的属性。3 字节码指令简介3.1字节码与数据类型在java虚拟机的指令集中,大多数的指令都包含了其操作所对应的数据类型信息,例如iload指令用于从局部变量表中加载int类型的数据到操作数栈中,而fload指令加载的则是float类型的数据。这两条指令的操作在虚拟机内部可能是同一段代码实现的,但在Class文件中它们必须拥有各自独立的操作码。大部分的指令都没有支持整数类型byte、char、short甚至没有任何指令支持boolean类型。大多数对于byte、char、short、boolean类型的操作,实际上都是使用相应的int类型作为运算符类型。3.2 加载和存储指令加载和存储指令用于将数据在栈帧中的局部变量表和操作数栈之间来回传输。3.3 运算指令运算或算术指令用于对操作数栈上的值进行某种特定运算,并把结果重新存入操作栈顶。大体上算术指令可以分为两种:对整型数据和对浮点数据进行运算指令。(由于没有byte、char、short、boolean类型,所以对这类数据的运算应使用int类型指令代替)3.4 类型转换指令类型转换指令可以将两种不同的数值类型进行相互转换。(比如int类型转换为float类型)小范围到大范围类型安全转换,无需显式的转换指令,否则必须显式的使用转换指令来完成。3.5 对象创建与访问指令虽然类实例和数组都是对象,但java虚拟机对类实例和数组的创建和操作使用了不同的字节码指令。3.6 操作数栈管理指令如同操作数据结构中的栈一样,java虚拟机也提供了一些用于直接操作操作数栈的指令,如:3.7 控制转移指令可以认为控制转移指令就是在有条件或无条件地修改PC寄存器的值。3.8 方法调用和返回指令invokevirtual 指令用于调用对象的实例方法invokeinterface指令用于调用接口方法invokespecial指令用于调用一些需要特殊处理的实例方法invokestatic指令用于调用类方法(static方法)invokedynamic指令用于在运行时动态解析出调用点限定符所使用的方法。方法调用指令与数据类型无关,而方法返回指令是根据返回值的类型区分的。3.9 异常处理指令在java虚拟机中,处理异常(catch语句)不是由字节码指令来实现的,而是采用异常表的方式。3.10 同步指令java虚拟机可以支持方法级的同步和方法内部一段指令序列的同步,这两种同步结构使用管程(Monitor)来支持的。4 虚拟机实现的两种方式将输入的java虚拟机代码在加载或执行时翻译成另外一种虚拟机的指令集将输入的java虚拟机代码在加载或执行时翻译成宿主主机CPU的本地指令集(即JIT代码生成技术)5 class文件结构的发展Class文件结构已经有十多年历史了,这10多年间,java技术体系有了翻天覆地的变化,但是Class文件结构一直处于比较稳定的状态,Class文件的主体结构、字节码指令的语义和数量几乎没有出现过变动,所有Class文件格式的改进,都集中在向访问标志、属性表这些在设计上就可扩展的数据结构中添加内容。总结:Class文件是java虚拟机执行引擎的数据入口,也是java技术体系的基础构成之一。本节主要介绍了Class文件结构中的各个部分,以及每个部分的定义、数据结构和使用方法。

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

推荐阅读更多精彩内容