揭秘Java虚拟机:JVM设计原理与实现
  • 推荐1
  • 收藏11
  • 浏览4.3K

揭秘Java虚拟机:JVM设计原理与实现

封亚飞 (作者) 

  • 书  号:978-7-121-31541-1
  • 出版日期:2017-07-07
  • 页  数:700
  • 开  本:16(185*230)
  • 出版状态:上市销售
  • 维护人:刘皎
纸质版 ¥129.00
《揭秘Java虚拟机:JVM设计原理与实现》从源码角度解读HotSpot的内部实现机制,本书主要包含三大部分——JVM数据结构设计与实现、执行引擎机制及内存分配模型。
  数据结构部分包括Java字节码文件格式、常量池解析、字段解析、方法解析。每一部分都给出详细的源码实现分析,例如字段解析一章,从源码层面详细分析了Java字段重排、字段继承等关键机制。再如方法解析一章,给出了Java多态特性在源码层面的实现方式。《揭秘Java虚拟机:JVM设计原理与实现》通过直接对源代码的分析,从根本上梳理和澄清Java领域中的关键概念和机制。
  执行引擎部分包括Java方法调用机制、栈帧创建机制、指令集架构与解释器实现机制。这一话题是《揭秘Java虚拟机:JVM设计原理与实现》技术含量高的部分,需要读者具备一定的汇编基础。不过千万不要被“汇编”这个词给吓着,其实在作者看来,汇编相比于高级语言而言,语法非常简单,语义也十分清晰。执行引擎部分重点描述Java源代码如何转换为字节码,又如何从字节码转换为机器指令从而能够被物理CPU所执行的技术实现。同时详细分析了Java函数堆栈的创建全过程,在源码分析的过程中,带领读者从本质上理解到底什么是Java函数堆栈和栈帧,以及栈帧内部的详细结构。
  内存分配部分主要包括类型创建与加载、对象实例创建与内存分配,例如new关键字的工作机制,import关键字的作用,再如java.lang.ClassLoader.loadClass()接口的本地实现机制。
  《揭秘Java虚拟机:JVM设计原理与实现》并不是简单地分析源码实现,而是在描述HotSpot内部实现机制的同时,分析了HotSpot如此这般实现的技术必然性。读者在阅读《揭秘Java虚拟机:JVM设计原理与实现》的过程中,将会在很多地方看到作者本人的这种思考。
Java工程师高质量成长的必读本。看透JVM设计思想与原理,彻底领悟JAVA编程精髓,以不变应万变!
推荐序
从Java诞生至今已有二十余年,基于虚拟机的技术屏蔽了底层环境的差异,“一次编译,随处运行”的思想促进了整个IT上层技术应用产生了翻天覆地的变化。Java作为服务端应用语言的首选,确实大大降低了学习和应用的门槛。现实生活中,绝大多数Java程序员对于虚拟机的原理和实现了解并不深入,也似乎并不那么关心。而随着互联网的极速发展,现在的Java服务端应用需要应对极高的并发访问和大量的数据交互,从机制和设计原理上了解虚拟机的核心原理和实现细节显然能够帮助Java程序员编写出更高效优质的代码。
虽然市面上从Java使用者角度介绍虚拟机的书也有不少佳作,但一般较为宽泛,尤其在谈及虚拟机如何运行、处理的细节时总有些浅尝辄止的遗憾。而作者凭借深厚的C与Java技术功底以及多年对于JVM的深入研究编写的这本书,真正从虚拟机指令执行处理层面,结合JVM规范的设计原理,完整和详尽地阐述了Java虚拟机在处理类、方法和代码时的设计和实现细节。书中大量的代码和指令细节能够让程序员更加直接地理解相关原理。
这是一本优秀的技术工具书,可以让阅读者更加深刻地理解虚拟机的原理和处理细节,值得每一位具有极客精神、追求细节的优秀程序员反复阅读和收藏。
——菜鸟平台技术部 陌铭

前言
文明需要创造,也需要传承。JVM作为一款虚拟机,本身便是技术之集大成者,里面包含方方面面的底层技术知识。抛开如今Java如日中天之态势不说,纯粹从技术层面看,JVM也值得广大技术爱好者深入研究。可以说,从最新的硬件特性,到最新的软件技术,只要技术被证明是成熟的,都会在JVM里面见到其踪影。JDK的每一次更新,从内部到核心类库,JVM都会及时引入这些最新的技术或者算法,这便是技术传承意义之所在。随着云计算、大数据、人工智能等最新技术的发展,Java技术生态圈也日益庞大,JVM与底层平台以及与其他编程语言和技术的交互、交织日益深入,这些都离不开对JVM内部机制的深入理解。如果说以前在中间件与框架领域的大展身手,依靠的是Java语言层面的特性和技术,那么以后越来越多的技术红利将会因JVM层面之创新而得以显现。
被真相所蒙蔽,是一件痛苦的事。我们在一个被层层封装的世界里进行开发和设计,操作系统、各种中间件与框架,将底层世界隐藏得结结实实。我们一方面享受着高级编程语言所带来的高效、稳定、快速的开发体验,然而另一方面,却又如同行走于黑暗之中。我们不知道路的下面是否有坑,即使有坑,可能也不知道如何排除。Java的很多概念和技术,很多时候由于我们对底层机制的不了解,而让我们感到十分高深莫测,无法知其全貌。这种感觉非常痛苦,尤其是技术修炼到一定阶段的时候。
纸上得来终觉浅,绝知此事要躬行。即使从Java语言层面下探到JVM层面,但是若只囿于对JVM机制理论和概念上的理解,很多时候仍然觉得缺乏那种大彻大悟之感。计算机作为一门科学,与其他的科学领域一样,不仅需要对其理论的理解,也需要能够去实证。例如爱因斯坦的相对论十分高深,但是通过对引力波和红移的观测,其变得形象和生动起来。Java的部分概念经过“口口相传”,似有过于夸大其技术神秘性之嫌,让人望而生畏。例如,与volatile关键字相关的内存可见性、指令乱序等概念,给人无比博大深奥的印象,但是如能抛开概念,直接看底层实现机制,并辅以具体的实验论证,则会形成深刻而彻底的认知。其实,这世界本来就很简单。在可观测的实验结果与可理解的底层机制面前,一切浮夸的概念都自然会现出原形。
因此,采用自底而上的技术研究之道,相比自顶而下的办法,便多了更多窥透本质的自信和平实。同一个底层概念,在不同的高级编程语言里,在概念、叫法上很少能够保持一致。采用自底而上的探索方法,能够揭开各种深奥概念的神秘面纱,还原一个清明简洁的世界。自然理解曲线也不会有大起大落。
研究JVM的过程,就是与大师们进行精神沟通和心灵交流的过程,虽然过程会比较痛苦。研究诸如Linux、JVM这样的底层程序,你能学习到大师级的理念,更能够见识到经无数牛人反复锤炼后的技术。天长日久的耳濡目染,终有一天你也会成为大师,你也会拥有大师级的眼光,你也会拥有开阔的胸怀。如同音乐家李健,人们如此喜欢他,并不仅仅是因为他歌唱得好,更多的是因为气质。而这种气质来自于博览群书,来自于对艺术的长久修炼。计算机从某种程度上而言,也是一门艺术,工程师和程序员们要想进化,对计算机艺术的修炼必不可少。与大师进行精神沟通,不仅能够修炼到计算机的艺术,更能直接感受并养成大师身上所具备的气质。
我不知道Java还能走多远,未来是否会被淘汰,但你不能因此就否定研究JVM的意义。JVM作为一款虚拟机,各种底层技术和理论都有涉及,若你能研究透彻,则能一通百通。例如,本人在研究过程中,也翻阅了诸如Python、JavaScript等高级面向对象语言虚拟机的机制,发现它们内部的整体思路都相差不大。同时,JVM本身在运行期干了一部分C或C++语言编译器所干的事,例如符号解析、链接、面向对象机制的实现等,通过对这些机制的分析,从来没有研究过C/C++编译器原理的我,基本也能够猜出C/C++编译器可能的实现方式,后来翻阅了相关资料,果不其然。理解编译与虚拟机的实现机制是一方面,另一方面,通过深挖JDK核心类库的内部实现,则能够深刻理解线程、并发、I/O等比较高深的技术内幕。例如Java NIO,何谓VMA?何谓内核映射?若想真正彻底理解这些概念,不从底层入手,恐怕很难有一个具象化的认知。总之,研究JVM,是一件非常能够提升开发者内功的事情,未来无论出现什么样的新语言、新技术、新概念,你总是能够不被表面的东西所迷惑,而是能够透过层层封装,看清事物的本质,你总是能够以极低的学习成本,迅速理解新的东西。从一个更为广阔的视角,使用发散的思维去看,不一定非要研究JVM才能有很大收获,研究其他技术的底层,会有异曲同工之妙。而我只不过恰好生在了这个年代,这个Java语言大行其道的年代,所以就恰好对其做了一个比较深入的研究而已。工具有时空疆界,而技术思想则没有,其总能穿越千万年的时空,无限延伸。
JVM涉及的知识面十分广阔,因此限于篇幅,本书并未覆盖JVM的全部内容。总体而言,本书重点描述了JVM从启动开始到完成函数执行的详细机制,读完本书,相信你一定能够明白JVM执行Java程序的底层机制,能够明白JVM将Java语言一步步转换为CPU可执行的机器码的内部机制,以及为此而制定的各种规范的实现之道,例如oop-klass模型、堆栈分配模型、类加载模型等。
本书作为笔者本人的处女作,前后写了有两年之久。之所以写这么久,一方面是因为JVM本身涉及大量的知识,另一方面则是笔者本人在写作过程中,力求对每一个知识点都做实验进行验证,避免因为笔者的错误理解而误导了别人。同时,在这个过程中,笔者不仅仅满足于读懂JVM的源代码,也不仅仅满足于通过实验去验证各个技术点,笔者花了更多的时间在思考JVM各种技术选择的必然性。换言之,在具体的硬件和操作系统的约束之下,在JVM“write once, run anywhere”这一思路设定下,JVM内部的技术实现机制是确定的,别无他法。例如,JVM的GC机制便是一种技术必然性选择。每一次对这种技术必然性之思考,就好像与JVM的作者大牛们进行了一次心灵交流。
我问大牛:JVM的堆栈结构为什么要有操作数栈和局部变量表?
大牛回答:因为……。
大牛其实并没有回答我,所有的一切都需要笔者自己去想明白。等想明白了之后,才有种真正看透事物本质的快感。
希望本书的读者也能够跟随本书,一起去进行这样的思考。
正是因为对“知其所以然”之追求,所以本书的写作过程是漫长的。在此,要特别感谢我的老婆金艳和我的儿子佑佑,很多个周末我都没能抽出时间陪伴他们。当我开始打算写作本书时,我的孩子还在襁褓之中。而等我写完本书,孩子已经开始上小班了。欠缺的太多!
JVM所涉及的知识面既广且深,而个人所知毕竟有限,书中定有错误之处,若有发现,请发送邮件至:chaomengyuexiang@126.com。
在写作本书的过程中,遇到了很多技术障碍,有很多技术障碍都是在查阅了R大以及阿里技术专家三红、寒泉子等人的文章后才得以攻克,在此表示感谢!向这些大牛致敬!
同时,也要感谢我的领导和同事所给予的大力支持,尤其要感谢菲青、陌铭、祝幽、兰博等人的鼓励,同时你们也是我学习的榜样!

目录

第1章 Java虚拟机概述 1
1.1 从机器语言到Java——詹爷,你好 1
1.2 兼容的选择:一场生产力的革命 6
1.3 中间语言翻译 10
1.3.1 从中间语言翻译到机器码 11
1.3.2 通过C程序翻译 11
1.3.3 直接翻译为机器码 13
1.3.4 本地编译 16
1.4 神奇的指令 18
1.4.1 常见汇编指令 20
1.4.2 JVM指令 21
1.5 本章总结 24
第2章 Java执行引擎工作原理:方法调用 25
2.1 方法调用 26
2.1.1 真实的机器调用 26
2.1.2 C语言函数调用 41
2.2 JVM的函数调用机制 47
2.3 函数指针 53
2.4 CallStub函数指针定义 60
2.5 _call_stub_entry例程 72
2.6 本章总结 115
第3章 Java数据结构与面向对象 117
3.1 从Java算法到数据结构 118
3.2 数据类型简史 122
3.3 Java数据结构之偶然性 129
3.4 Java类型识别 132
3.4.1 class字节码概述 133
3.4.2 魔数与JVM内部的int类型 136
3.4.3 常量池与JVM内部对象模型 137
3.5 大端与小端 143
3.5.1 大端和小端的概念 146
3.5.2 大小端产生的本质原因 148
3.5.3 大小端验证 149
3.5.4 大端和小端产生的场景 151
3.5.5 如何解决字节序反转 154
3.5.6 大小端问题的避免 156
3.5.7 JVM对字节码文件的大小端处理 156
3.6 本章总结 159
第4章 Java字节码实战 161
4.1 字节码格式初探 161
4.1.1 准备测试用例 162
4.1.2 使用javap命令分析字节码文件 162
4.1.3 查看字节码二进制 165
4.2 魔数与版本 166
4.2.1 魔数 168
4.2.2 版本号 168
4.3 常量池 169
4.3.1 常量池的基本结构 169
4.3.2 JVM所定义的11种常量 170
4.3.3 常量池元素的复合结构 170
4.3.4 常量池的结束位置 172
4.3.5 常量池元素总数量 172
4.3.6 第一个常量池元素 173
4.3.7 第二个常量池元素 174
4.3.8 父类常量 174
4.3.9 变量型常量池元素 175
4.4 访问标识与继承信息 177
4.4.1 access_flags 177
4.4.2 this_class 178
4.4.3 super_class 179
4.4.4 interface 179
4.5 字段信息 180
4.5.1 fields_count 180
4.5.2 field_info fields[fields_count] 181
4.6 方法信息 185
4.6.1 methods_count 185
4.6.2 method_info methods[methods_count] 185
4.7 本章回顾 205
第5章 常量池解析 206
5.1 常量池内存分配 208
5.1.1 常量池内存分配总体链路 209
5.1.2 内存分配 215
5.1.3 初始化内存 223
5.2 oop-klass模型 224
5.2.1 两模型三维度 225
5.2.2 体系总览 227
5.2.3 oop体系 229
5.2.4 klass体系 231
5.2.5 handle体系 234
5.2.6 oop、klass、handle的相互转换 239
5.3 常量池klass模型(1) 244
5.3.1 klassKlass实例构建总链路 246
5.3.2 为klassOop申请内存 249
5.3.3 klassOop内存清零 253
5.3.4 初始化mark 253
5.3.5 初始化klassOop._metadata 258
5.3.6 初始化klass 259
5.3.7 自指 260
5.4 常量池klass模型(2) 261
5.4.1 constantPoolKlass模型构建 261
5.4.2 constantPoolOop与klass 264
5.4.3 klassKlass终结符 267
5.5 常量池解析 267
5.5.1 constantPoolOop域初始化 268
5.5.2 初始化tag 269
5.5.3 解析常量池元素 271
5.6 本章总结 279
第6章 类变量解析 280
6.1 类变量解析 281
6.2 偏移量 285
6.2.1 静态变量偏移量 285
6.2.2 非静态变量偏移量 287
6.2.3 Java字段内存分配总结 312
6.3 从源码看字段继承 319
6.3.1 字段重排与补白 319
6.3.2 private字段可被继承吗 325
6.3.3 使用HSDB验证字段分配与继承 329
6.3.4 引用类型变量内存分配 338
6.4 本章总结 342
第7章 Java栈帧 344
7.1 entry_point例程生成 345
7.2 局部变量表创建 352
7.2.1 constMethod的内存布局 352
7.2.2 局部变量表空间计算 356
7.2.3 初始化局部变量区 359
7.3 堆栈与栈帧 368
7.3.1 栈帧是什么 368
7.3.2 硬件对堆栈的支持 387
7.3.3 栈帧开辟与回收 390
7.3.4 堆栈大小与多线程 391
7.4 JVM的栈帧 396
7.4.1 JVM栈帧与大小确定 396
7.4.2 栈帧创建 399
7.4.3 局部变量表 421
7.5 栈帧深度与slot复用 433
7.6 最大操作数栈与操作数栈复用 436
7.7 本章总结 439
第8章 类方法解析 440
8.1 方法签名解析与校验 445
8.2 方法属性解析 447
8.2.1 code属性解析 447
8.2.2 LVT&LVTT 449
8.3 创建methodOop 455
8.4 Java方法属性复制 459
8.5 461
8.6 查看运行时字节码指令 482
8.7 vtable 489
8.7.1 多态 489
8.7.2 C++中的多态与vtable 491
8.7.3 Java中的多态实现机制 493
8.7.4 vtable与invokevirtual指令 500
8.7.5 HSDB查看运行时vtable 502
8.7.6 miranda方法 505
8.7.7 vtable特点总结 508
8.7.8 vtable机制逻辑验证 509
8.8 本章总结 511
第9章 执行引擎 513
9.1 执行引擎概述 514
9.2 取指 516
9.2.1 指令长度 519
9.2.2 JVM的两级取指机制 527
9.2.3 取指指令放在哪 532
9.2.4 程序计数器在哪里 534
9.3 译码 535
9.3.1 模板表 535
9.3.2 汇编器 540
9.3.3 汇编 549
9.4 栈顶缓存 558
9.5 栈式指令集 565
9.6 操作数栈在哪里 576
9.7 栈帧重叠 581
9.8 entry_point例程机器指令 586
9.9 执行引擎实战 588
9.9.1 一个简单的例子 588
9.9.2 字节码运行过程分析 590
9.10 字节码指令实现 597
9.10.1 iconst_3 598
9.10.2 istore_0 599
9.10.3 iadd 600
9.11 本章总结 601
第10章 类的生命周期 602
10.1 类的生命周期概述 602
10.2 类加载 605
10.2.1 类加载——镜像类与静态字段 611
10.2.2 Java主类加载机制 617
10.2.3 类加载器的加载机制 622
10.2.4 反射加载机制 623
10.2.5 import与new指令 624
10.3 类的初始化 625
10.4 类加载器 628
10.4.1 类加载器的定义 628
10.4.2 系统类加载器与扩展类加载器创建 634
10.4.3 双亲委派机制与破坏 636
10.4.4 预加载 638
10.4.5 引导类加载 640
10.4.6 加载、链接与延迟加载 641
10.4.7 父加载器 645
10.4.8 加载器与类型转换 648
10.5 类实例分配 649
10.5.1 栈上分配与逃逸分析 652
10.5.2 TLAB 655
10.5.3 指针碰撞与eden区分配 657
10.5.4 清零 658
10.5.5 偏向锁 658
10.5.6 压栈与取指 659
10.6 本章总结 661

读者评论

  • P168,4.2.2节,关于class文件的版本号的说法似乎是有问题,此处的文字和图片都指出,前两个字节是主版本号,后两个是副版本号,此处有误。
    根据J**a虚拟机规范,class文件中,版本号的前两个字节是副版本,后两个字节是主版本。

    枫山别院发表于 2019/10/23 21:27:49
    • https://www.firfor.cn/articles/2022/01/31/1643608589191.html

      根据规范:
      https://docs.oracle.com/j**ase/specs/jvms/se7/html/jvms-4.html#jvms-4.1
      先小,后大.

      firfor发表于 2022/7/3 0:41:30
  • 第五章5.2.6节,第243页中举得例子关于内存student的内存示意图是错误的。klassobj是被共享的,不是跟随每一个instanceoop。另外通过hdsb可以看出吧。这一页讨论的都是klassoop klass*之间的转换。你的例子则是关于instanceoop

    abortexit发表于 2018/6/18 11:53:00
  • 第四章 4.2.2关于字节码文件主版本号和次版本号描述和截图是不是反了?

    yhl_jxy发表于 2018/5/27 12:19:34
    • 目前看是反了

      shihy发表于 2019/11/8 19:35:14
  • 看网站这么冷清就知道是价格贵造成的。买了纸质后电子书还是原价。图灵是一折,异步是四折。也没有定期活动。差距立见。这本书在亚马逊买了真的是为了尊重作者而且又是自己需要的。。其他书表示只能很惭愧的看db

    Jensonss发表于 2017/8/25 15:17:06
    • 同意楼上。 这本书怎么样?今年刚出版,销量就挺高,搜索了一下作者,网上基本没有作者的信息,在考虑要不要买啊。

      seachal发表于 2017/8/26 9:37:47
    • 我是这本书的作者,非常感谢你对本书的支持!

      封亚飞发表于 2017/9/5 14:43:50
    • @seachal 我联系下出版社,为什么没有我的个人信息。我在阿里工作,主要从事云平台、中间件的研发。这本书我花了足足2年的时间认真写的第一本处女作,感谢支持哈!

      封亚飞发表于 2017/9/5 14:44:58

相关博文

  • 类加载与Java主类加载机制解析

    类加载与Java主类加载机制解析

    管理员账号 2017-08-23

    小编说:类的加载机制与生命周期等概念,在各种书籍与各种网络博客里随处可见,然而对于一个想要真正了解其内部实现的人而言,那些都涉入过浅。本文从JVM源码的角度,还原出Java类加载的真实机制。 本文选自《揭秘Java虚拟机:JVM设计原...

    管理员账号 2017-08-23
    1197 0 0 0

推荐用户

相关图书

Python一行流:像专家一样写代码

Christian Mayer (作者) 苏丹 (译者)

本书专注于从初学迈向进阶的Python编码技术:如何像专家一样写出优雅、准确、简洁高效的Python 单行代码;阅读任意一行Python 代码时,如何系统性地对...

¥89.00

剑指Offer(专项强化版):数据结构与算法名企面试题精讲

何海涛 (作者)

本书全面、系统地总结了在准备程序员面试过程中必备的数据结构与算法。本书首先详细讨论整数、数组、链表、字符串、哈希表、栈、队列、二叉树、堆和前缀树等常用的数据结构...

¥89.00

C++服务器开发精髓

张远龙 (作者)

本书从操作系统原理角度讲解进行C++服务器开发所需掌握的技术栈。全书总计9章,第1~2章讲解C++ 11/14/17新标准中的常用特性、新增类库,以及C++开发...

 

PHP编程(第4版)

Rasmus Lerdorf(拉斯马斯·勒多夫), Kevin Tatroe(凯文·塔特罗), Peter MacIntyre(彼得·麦金太尔) (作者) 卢涛 (译者)

PHP是一种被广泛使用的Web编程语言,它简单易用,而且与时俱进,不断进化,提升性能。本书基于PHP 7.4,深入介绍 PHP编程技术,涵盖了 PHP 所有基本...

¥109.00

深入理解Spring Cloud与实战

方剑 (作者)

本书共分10章,主要介绍Spring Cloud各个核心组件的设计原理,以及目前流行的Spring Cloud Alibaba和 Netflix组件,并且剖析S...

¥106.00

基于Kotlin的Spring Boot微服务实战

袁康 (作者)

本书介绍了Kotlin在Spring Boot微服务开发中的实践,并使用Kotlin作为开发语言,介绍了函数式编程思想、Kotlin的语法、Kotlin在常用中...

¥69.30