科技>计算机>编程语言
Java虚拟机精讲

Java虚拟机精讲"

作者:高翔龙
ISBN:9787121257056
定价:¥69.0
字数:448千字
页数:280
出版时间:2015-05
开本:16(185*235)
版次:01-01
装帧:
出版社:电子工业出版社
简介

HotSpot VM 是目前市面上高性能JVM 的代表作之一,它采用解释器+JIT 编译器的混合执行引擎,使得Java 程序的执行性能从此有了质的飞跃。本书以极其精练的语句诠释了HotSpot VM 的方方面面,比如:字节码的编译原理、字节码的内部组成结构、通过源码的方式剖析HotSpot VM 的启动过程和初始化过程、Java 虚拟机的运行时内存、垃圾收集算法、垃圾收集器(重点讲解了Serial 收集器、ParNew 收集器、Parallel 收集器、CMS(Concurrent-Mark-Sweep)收集器和G1(Garbage-First)收集器)、类加载机制,以及HotSpot VM 基于栈的架构模型和执行引擎(解释器的工作流程、JIT 编译器的工作流程、分层编译策略、热点探测功能)等技术。

前言

大部分 Java 开发人员,除会在项目中使用到与 Java 平台相关的各种高精尖技术,对于 Java技术的核心 Java 虚拟机了解甚少。这其中最主要的原因或许是在实际的开发过程中,开发人员根本没有机会或是没有必要与 Java 虚拟机等底层技术打交道,更多的只是简简单单地将Java 虚拟机作为载体,让程序能够顺利运行其上即可。 笔者在面试的过程中,经常会对面试者询问一些与 Java 虚拟机相关的技术问题,但大部 分开发人员对于笔者所提及的问题,几乎都有一个统一的答案,那就是不知道、不清楚。有些刚从校门出来的应届毕业生,甚至还包括一些有一定工作经验的开发人员,打心眼儿里觉得 Struts、Spring 和 Hibernate 等上层技术才是重点,基础技术并不重要,这其实是一种本末倒置的“病态”。这就好比金庸武侠小说《笑傲江湖》里的令狐冲,尽管独孤九剑看上去很酷炫,但由于本身内功修炼得不够,与敌人对抗时又能撑得了几个回合呢? 对于那些成熟的第三方开源产品,笔者始终只是把它们当作一种工具,用的时候是宝, 不用的时候就丢弃,尽管有些残忍,但确实就是这么现实。以互联网项目为例,对于高性能和稳定性的要求往往大于企业级项目的规范化和流程化,因此架构师每天都会不停地思考,应该如何让我的系统更快?如何避免系统出现瓶颈?如果换作你来做架构师并负责解决这些问题,假如你对 Java 虚拟机一无所知,那么可想而知,你又有什么能力做到系统的性能调优?毕竟性能调优不仅仅只是单纯地从应用代码结构上进行调整,也不是纯粹地依靠物理堆机就能够解决的。 创作此书的目的 尽管并不是所有开发人员都能够在实际的项目开发过程中用到与 Java 虚拟机相关的优化 技术,但这并不能够成为你不去了解 Java 虚拟机的理由。只要你从事的是与 Java 开发相关的岗位,那么对 Java 虚拟机实现机制的了解就是你迟早必须攀爬的一座高山。如果你害怕,那么你将永远也无法屹立在山顶遥望最美的日出。 其实这几年国内也不乏一些比较优秀的技术作者创作了一些知名度比较高的有关 Java 虚 拟机的作品。但是这些作品的创作初衷完全不同,一些完全是以理论为重心,而另外一些则完全是从底层源码实战出发为读者诠释 Java 虚拟机的实现细节。尽管这些作品都非常优秀,但笔者认为还不够简单,毕竟所面向的读者更多的是对 Java 虚拟机有一定程度了解的开发人员,对于从未接触过 Java 虚拟机的读者,或许会感觉到有些手足无措的挫败感。因此笔者创作此书的目的,在更大程度上是以更为精练的语句引读者入门 Java 虚拟机的世界。换句话说,你完全可以将本书看作一个跳板,当你熟知本书的内容后,如果有一种饥渴难耐的感觉,那么恭喜你,笔者建议你阅读难度更大的书籍,同时本书的目的也就达到了。 本书所面向的读者 本书适用于任何对 Java 虚拟机感兴趣的 Java 开发人员、系统架构师、Java 虚拟机爱好者。尤其是对于那些从未接触过 Java 虚拟机的 Java 开发人员,本书笔者竭尽所能用最精练和直接的语句诠释了有关 Java 虚拟机的方方面面,只要你熟练掌握了 Java 编程基础,那么阅读本书你将不会感觉到任何的吃力和枯燥乏味。 本书内容 本书的内容包括字节码的编译原理、字节码的内部组成结构、通过源码的方式剖析HotSpot VM 的启动过程和初始化过程、Java 虚拟机的运行时内存、垃圾收集算法、垃圾收集器[重点讲解了 Serial 收集器、ParNew 收集器、Parallel 收集器、CMS(Concurrent-Mark-Sweep)收集器和 G1(Garbage-First)收集器]、类加载机制,以及 HotSpot VM 基于栈的架构模型和执行引擎(解释器的工作流程、JIT 编译器的工作流程、分层编译策略、热点探测功能)等技术。 从本书的第 1 章开始,笔者首先对 Java 的体系结构做了一个简单且全面的介绍,让大家 深刻认识到了 Java 虚拟机在 Java 平台中所占的分量,然而这一章的重点则是在 OpenJDK 和HotSpot VM 的编译实战任务上。当大家对 Java 虚拟机有了一个简单的了解后,本书的第 2 章则开始对字节码的编译原理进行了讲解,因为大家有必要了解 Java 语言规范与 JVM 规范之间的区别,以及 Java 代码究竟需要经历哪些步骤之后才能够被编译为一个有效的字节码文件。 而本书的第 3 章则与上一章息息相关,当大家了解字节码的编译原理后,接下来笔者将会对字节码的内部组成结构进行深入讲解。本书的第 4~6 章涉及 HotSpot VM 的部分源码实现,从Launcher 启动 HotSpot VM 开始,到 HotSpot VM 的初始化过程都是每一个 Java 开发人员必须掌握和了解的。对于大部分 Java 开发人员而言,对 Java 虚拟机最感兴趣的内容莫过于内存管理和垃圾收集,本书用了大量的篇幅来对这些技术进行讲解,并且对 Java7 新增的 G1 收集器也做了介绍。在本书的第 7 章中,笔者对类加载机制进行了讲解,帮助大家对类的初始化过程理解透彻。然而在本书的最后一章中,笔者对 HotSpot VM 的架构模型和执行引擎进行了深入讲解,毕竟执行引擎是 Java 虚拟机中最重要同时也是最核心的部分,运行时编译技术使得 Java程序的运行性能从此有了质的飞越。 参考文献 笔者在本书的创作过程中,从下面所列的这些参考资料中获取了极大的帮助,大家同时也 可以通过如下信息找到更多关于 Java 虚拟机方面的资料,毕竟单靠一本书就想了解Java 虚拟机的所有技术细节几乎是不可能的,更是不现实的。 □ 《Java 虚拟机规范 Java SE7 版》 [美] Tim Lindholm、Frank Yellin、Gilad Bracha、Alex Buckley 著; □ 《深入 Java 虚拟机 第 2 版》 [美] Bill Venners 著; □ 《Java 性能优化权威指南》 [美]Charlie Hunt、Binu John 著; □ 《深入理解 Java 虚拟机 第 2 版》周志明 著; □ 《HotSpot 实战》 陈涛 著; □ 《程序员》2014 年 3 月刊《中间语言和虚拟机漫谈》 徐宥 著; □ 《JVM 分享:Java Program in Action》 Rednaxelafx(莫枢) 著; □ 《HotSpot 内存管理白皮书》。 感谢 此书献给我这辈子最爱的姥爷。从我诞生那天起,您就将您的慈爱毫不吝啬地给予了我, 感谢您和姥姥从小对我的陪伴和照顾,是你们让我拥有了愉快的童年,让我体会到了亲情的温暖。我记得小时候家里的鹦鹉、画眉鸟是您最爱的宠物,您会每天带着它们出去散步,而如今却成为了我心中永远的回忆。姥爷,2014 年 05 月 09 日早上 7 点 20 分,当我最后在您耳边说完悄悄话后,您走了,带走了我的思念!姥爷,我一定会成为您这辈子的骄傲!除此之外,我们家可爱的小娇娇同学,谢谢你的支持和鼓励才让我有创作此书的勇气和动力,谢谢你,我爱你! 接下来要感谢的是 Rednaxelafx(莫枢)和蔡学镛,您二位在百忙之中抽空阅读了本书,提出了许多宝贵的意见,没有你们的支持或许本书至今也无法顺利出版。 最后还要感谢的是电子工业出版社博文视点的所有编辑们,谢谢你们无条件忍受着我一 再的跳票,本书能够顺利出版离不开你们如此敬业的精神和一丝不苟的工作态度,由衷地谢谢你们。 高翔龙 2015 年 3 月

目录

第 1 章 Java 体系结构.......................................1 1.1 认识 Java................................................1 1.1.1 与生俱来的优点.........................2 1.1.2 语法结构和对象模型..................4 1.1.3 历史版本追溯.............................5 1.2 Java 重要概念.......................................7 1.2.1 Java 编程语言.............................7 1.2.2 字节码.........................................7 1.2.3 Java API.......................................8 1.2.4 Java 虚拟机.................................8 1.3 安装与配置 Java 运行环境..............10 1.3.1 Windows 环境下的安装与 配置...........................................10 1.3.2 Linux 环境下的安装与配置.....11 1.3.3 编写 Java 程序..........................12 1.3.4 编译与运行...............................13 1.3.5 关键字与标示符.......................13 1.4 Java 技术的新特性............................14 1.4.1 Java 模块化与 OSGi 技术........14 1.4.2 语言无关性...............................15 1.4.3 使用 Fork/Join 框架实现多 核并行.......................................16 1.4.4 丰富的语法特性.......................17 1.4.5 过渡到 64 位虚拟机.................18 1.5 实战:玩转 OpenJDK.......................19 1.5.1 JDK 与 OpenJDK 的关系.........19 1.5.2 基于 OpenJDK 深度定制的 淘宝 JVM(TaobaoVM)........20 1.5.3 下载 OpenJDK 源代码.............22 1.5.4 构建编译环境...........................22 1.5.5 执行整个 OpenJDK 的编译.....23 1.5.6 执行单独 HotSpot 的编译........26 1.5.7 导致编译失败的一些疑难 杂症...........................................29 1.5.8 使用 GDB 工具 Debug HotSpot......................................30 1.6 本章小结..............................................36 第 2 章 字节码的编译原理.............................37 2.1 javac 编译器简介...............................37 2.1.1 javac 与 Eclipse Compiler for Java 编译器...............................38 2.1.2 javac 的使用与标准选项配置..39 2.1.3 编译原理...................................40 2.1.4 下载 javac 编译器源码.............41 2.1.5 调用 compile()方法执行编译...41 2.2 词法解析步骤.....................................43 2.2.1 Token 序列................................45 2.2.2 源码字符集合与 Token 之间 的对应关系...............................47 2.2.3 调用 key()方法获取指定 Token.........................................48 2.2.4 调用 nextToken()方法计算 Token 的获取规则....................48 2.2.5 调用 parseCompilationUnit() 方法执行词法解析...................49 2.3 语法解析步骤.....................................51 2.3.1 调用 qualident()方法解析 package 语法节点.....................52 2.3.2 调用 importDeclaration() 方法解析 import 语法树...........54 2.3.3 调用 classDeclaration() 方法解析 class 语法树..............56 2.4 语义解析步骤.....................................59 2.5 生成字节码..........................................61 2.6 实战:使用 javap 工具分析 字节码...................................................62 2.7 实战:使用 GCJ 编译器将 Java 源码直接编译为本地机器指令......64 2.8 本章小结..............................................66 第 3 章 字节码文件...........................................67 3.1 字节码文件的内部组成结构...........67 3.2 符号引用..............................................73 3.2.1 类或者接口的全限定名............74 3.2.2 简单名称...................................74 3.2.3 描述符.......................................74 3.3 常量池..................................................76 3.3.1 CONSTANT_Utf8_info 常量项.......................................77 3.3.2 CONSTANT_Integer_info 常量项.......................................77 3.3.3 CONSTANT_Float_info 常量项.......................................78 3.3.4 CONSTANT_Long_info 常量项.......................................78 3.3.5 CONSTANT_Double_info 常量项.......................................79 3.3.6 CONSTANT_Class_info 常量项.......................................79 3.3.7 CONSTANT_String_info 常量项.......................................80 3.3.8 CONSTANT_Fieldref_info 常量项.......................................81 3.3.9 CONSTANT_Methodref_info 常量项.......................................81 3.3.10 CONSTANT_InterfaceMethodref _info 常量项............................82 3.3.11 CONSTANT_NameAndType _info 常量项............................82 3.3.12 CONSTANT_MethodHandle _info 常量项............................83 3.3.13 CONSTANT_MethodType _info 常量项............................84 3.3.14 CONSTANT_InvokeDynamic _info 常量项............................84 3.4 字段表..................................................85 3.5 方法表..................................................86 3.6 属性表..................................................88 3.6.1 Code 属性..................................89 3.6.2 ConstantValue 属性..................90 3.6.3 Exceptions 属性........................91 3.6.4 LineNumberTable 属性.............92 3.6.5 SourceFile 属性.........................93 3.6.6 LocalVariableTable 属性..........93 3.6.7 InnerClasses 属性......................94 3.6.8 BootstrapMethods 属性.............95 3.7 本章小结..............................................96 第 4 章 剖析 HotSpot 的 Launcher..............97 4.1 HotSpot 的源码目录结构.................97 4.2 Launcher 简介.....................................99 4.3 跟踪 Launcher 的执行过程............101 4.3.1 使用 Launcher 启动 JVM........101 4.3.2 启动函数 main()......................102 4.3.3 在主线程中执行 JavaMain() 函数.........................................106 4.3.4 调用 JNI_CreateJavaVM() 函数初始化 HotSpot...............114 4.3.5 调用 LoadClass()函数获取 Java 启动类.............................115 4.3.6 调用 GetStaticMethodId() 函数获取 Java 启动方法.........116 4.3.7 调用 CallStaticVoidMethod() 函数执行 Java 启动方法.........116 4.3.8 调用 jni_DestroyJavaVM 函数销毁 HotSpot...................119 4.4 实战:在 Launcher 中添加 自定义函数模块...............................120 4.5 本章小结............................................121 第 5 章 剖析 HotSpot 的初始化过程..........122 5.1 HotSpot 的构成模块........................122 5.2 Prims 模块.........................................124 5.2.1 JNI 子模块...............................124 5.2.2 JVM 子模块............................125 5.2.3 JVMTI 子模块.........................128 5.2.4 Perf 子模块..............................129 5.3 Runtime 模块.....................................129 5.3.1 Thread 子模块.........................131 5.3.2 调用 create_vm()函数完成 HotSpot 的最终初始化...........131 5.4 跟踪 HotSpot 的初始化过程..........140 5.4.1 调用 init()和 init_2()函数 初始化 os 模块........................141 5.4.2 调用 vm_init_globals()函数 初始化全局数据结构.............144 5.4.3 调用 init_globals()函数 初始化全局模块.....................144 5.5 本章小结............................................146 第 6 章 内存分配与垃圾回收.......................147 6.1 JVM 的运行时内存区结构............147 6.2 线程共享内存区..............................148 6.2.1 Java 堆区.................................148 6.2.2 方法区.....................................150 6.2.3 运行时常量池.........................150 6.3 线程私有内存区..............................150 6.3.1 PC 寄存器...............................151 6.3.2 Java 栈.....................................151 6.3.3 本地方法栈.............................152 6.4 性能监控区.......................................152 6.5 自动内存管理...................................152 6.5.1 内存分配原理.........................153 6.5.2 逃逸分析与栈上分配.............157 6.5.3 对象内存布局与 OOP-Klass 模型.........................................158 6.5.4 GC 的作用..............................159 6.5.5 垃圾标记:根搜索算法.........160 6.5.6 垃圾回收:分代收集算法.....161 6.6 垃圾收集器.......................................164 6.6.1 串行回收:Serial 收集器.......165 6.6.2 并行回收:ParNew 收集器...166 6.6.3 程序吞吐量优先:Parallel 收集器.....................................166 6.6.4 低延迟:CMS(Concurrent- Mark-Sweep)收集器.............167 6.6.5 区域化分代式:G1(Garbage- First)收集器..........................170 6.6.6 垃圾收集的相关选项配置......172 6.7 实战:GC 日志分析........................175 6.7.1 不同 GC 日志的展示形式......175 6.7.2 使用 GCHisto 工具分析离线 日志.........................................179 6.8 实战:分析 dump 文件...................181 6.8.1 使用 jmap 工具生成 dump 文件.........................................181 6.8.2 使用 MAT(Memory Analyzer Tool)工具分析 dump 文件...182 6.9 本章小结............................................184 第 7 章 类加载机制.........................................185 7.1 类加载器............................................185 7.1.1 抽象类 ClassLoader.................187 7.1.2 双亲委派模型.........................188 7.1.3 自定义类加载器.....................191 7.1.4 定位 ClassNotFoundException 异常.........................................193 7.1.5 定位 NoClassDefFoundError 异常.........................................194 7.2 类的加载过程...................................195 7.2.1 加载字节码.............................198 7.2.2 验证阶段.................................199 7.2.3 准备阶段.................................200 7.2.4 解析阶段.................................201 7.2.5 初始化阶段.............................201 7.3 实战:字节码文件的加密与 解密.....................................................204 7.4 本章小结............................................208 第 8 章 剖析 HotSpot 的架构模型与 执行引擎.............................................209 8.1 栈帧的组成结构...............................209 8.1.1 局部变量表.............................211 8.1.2 操作数栈.................................212 8.1.3 动态链接.................................214 8.1.4 方法返回值.............................216 8.2 HotSpot 中执行引擎的架构 模型....................................................216 8.2.1 本地机器指令.........................217 8.2.2 寄存器架构与栈式架构之间 的区别.....................................218 8.2.3 基于栈式架构的设计.............221 8.2.4 调用 call_stub()函数执行 Java 方法.........................................222 8.2.5 栈顶缓存(Top-of-Stack Cashing) 技术.........................................225 8.2.6 实战:跟踪字节码解释器的 执行步骤.................................227 8.3 解释器与 JIT 编译器......................230 8.3.1 查阅 HotSpot 的运行时执 行模式.....................................231 8.3.2 解释器的工作机制与构成 模块.........................................232 8.3.3 JIT 编译器的工作机制与 构成模块.................................234 8.3.4 分层编译策略.........................235 8.3.5 热点探测功能.........................236 8.4 本章小结............................................239 附录 A Java7 新增语法特性........................241 A.1 try-with-resources 语句..................241 A.2 泛型的“<>”类型推断运算符...245 A.3 声明二进制字面值.........................247 A.4 字面值下画线支持.........................248 A.5 switch 表达式支持 String 类型....250 A.6 mutil-catch 特性..............................251 A.7 NIO2.0 文件系统的改变...............255 附录 B 指令助记符.........................................262

作者简介

编辑推荐

作者寄语

电子资料

www.luweidong.cn

下一个