标题：深入理解Java虚拟机：JVM高级特性与最佳实践
图书信息
作者:周志明
丛书名:华章原创精品
出版社：机械工业出版社
ISBN：9787111349662
  出版日期：2011年6月
开本：16开
页码：387
内容简介
作为一位java程序员，你是否也曾经想深入理解java虚拟机，但是却被它的复杂和深奥拒之门外？没关系，《深入理解java虚拟机:jvm高级特性与最佳实践》极尽化繁为简之妙，能带领你在轻松中领略java虚拟机的奥秘。《深入理解java虚拟机:jvm高级特性与最佳实践》是近年来国内出版的唯一一本与java虚拟机相关的专著，也是唯一一本同时从核心理论和实际运用这两个角度去探讨java虚拟机的著作，不仅理论分析得透彻，而且书中包含的典型案例和最佳实践也极具现实指导意义。
全书共分为五大部分。第一部分从宏观的角度介绍了整个java技术体系的过去、现在和未来，以及如何独立地编译一个openjdk7，这对理解后面的内容很有帮助。第二部分讲解了jvm的自动内存管理，包括虚拟机内存区域的划分原理以及各种内存溢出异常产生的原因；常见的垃圾收集算法以及垃圾收集器的特点和工作原理；常见的虚拟机的监控与调试工具的原理和使用方法。第三部分分析了虚拟机的执行子系统，包括class的文件结构以及如何存储和访问class中的数据；虚拟机的类创建机制以及类加载器的工作原理和它对虚拟机的意义；虚拟机字节码的执行引擎以及它在实行代码时涉及的内存结构。第四部分讲解了程序的编译与代码的优化，阐述了泛型、自动装箱拆箱、条件编译等语法糖的原理；讲解了虚拟机的热点探测方法、hotspot的即时编译器、编译触发条件，以及如何从虚拟机外部观察和分析jit编译的数据和结果。第五部分探讨了java实现高效并发的原理，包括jvm内存模型的结构和操作；原子性、可见性和有序性在java内存模型中的体现；先行发生原则的规则和使用；线程在java语言中的实现原理；虚拟机实现高效并发所做的一系列锁优化措施。
《深入理解java虚拟机:jvm高级特性与最佳实践》适合所有java程序员、系统调优师和系统架构师阅读。
媒体评论
Java 程序是如何运行的？Java虚拟机在其中扮演了怎样的角色？如何让Java程序具有更高的并发性？许多Java程序员都会诸如此类的疑问。无奈，国内在很长一段时间里都没有一本从实际应用的角度讲解Java虚拟机的著作，《深入理解Java虚拟机:JVM高级特性与最佳实践》的出版可谓填补了这个空白。它从Java程序员的角度出发，系统地将Java程序运行过程中涉及的各种知识整合到了一起，并配以日常工作中可能会碰到的疑难案例，引领读者轻松踏上探索Java虚拟机的旅途，是广大对Java虚拟机感兴趣的读者的福音！——莫枢（RednaxelaFX） 虚拟机和编程语言爱好者 
在武侠的世界里，无论是至刚至强的《易筋经》，还是阴柔无比的《葵花宝典》，都离不开内功修炼。没有了内功心法，这些武术只是花拳绣腿的拙劣表演而已。软件业是武林江湖的一个翻版，也有着大量的模式、套路、规范等外功，但“外功修行，内功修神”，要想成为“扫地僧”一样的绝世高人，此书是必备的。——秦小波 资深Java技术专家/著有畅销书《设计模式之禅》 
对Java程序员来说，Java虚拟机可以说是既熟悉又神秘，很少Java程序员能够抑制自己探究它的冲动。可惜，分析JVM实现原理的书籍（特别是国内作者出版的）是少之又少。《深入理解Java虚拟机:JVM高级特性与最佳实践》的出版可谓Java程序员的福音，作者将自己多年来在Java虚拟机领域的实践经验和研究心得呈现在了这《深入理解Java虚拟机:JVM高级特性与最佳实践》中，不仅系统地讲解了Java虚拟机工作机制和底层原理，而且更难能可贵的是与实践很好地结合了起来，具有非常强的实践指导意义，强烈推荐！——计文柯 资深Java技术专家/著有畅销书《Spring技术内幕：深入解析Spring架构设计与实现原理》
作译者简介
周志明，资深Java技术专家，对JavaEE企业级应用开发、OSGi、Java虚拟机和工作流等都有深入的研究，并在大量的实践中积累了丰富的经验。尤其精通Java虚拟机，撰写了大量与JVM相关的经典文章，被各大技术社区争相转载，是ITeye等技术社区公认的Java虚拟机方面的领袖人物之一。现任远光软件股份有限公司平台开发部经理兼平台架构师，先后参加与过国家电网、南方电网等多个国家级大型ERP项目的平台架构工作，对软件系统架构也有深刻的认识和体会。
前言
Java是目前用户最多、使用范围最广的软件开发技术，Java的技术体系主要由支撑Java程序运行的虚拟机、为各开发领域提供接口支持的Java API、Java编程语言及许许多多的第三方Java框架（如Spring和Struts等）构成。在国内，有关Java API、Java语言及第三方框架的技术资料和书籍非常丰富，相比之下，有关Java虚拟机的资料却显得异常贫乏。
这种状况很大程度上是由Java开发技术本身的一个重要优点导致的：在虚拟机层面隐藏了底层技术的复杂性以及机器与操作系统的差异性。运行程序的物理机器情况千差万别，而Java虚拟机则在千差万别的物理机上面建立了统一的运行平台，实现了在任意一台虚拟机上编译的程序都能在任何一台虚拟机上正常运行。这一极大的优势使得Java应用的开发比传统C/C++应用的开发更高效和快捷，程序员可以把主要精力集中在具体业务逻辑上，而不是物理硬件的兼容性上。一般情况下，一个程序员只要了解了必要的Java API、Java语法并学习适当的第三方开发框架，就已经基本能满足日常开发的需要了，虚拟机会在用户不知不觉中完成对硬件平台的兼容以及对内存等资源的管理工作。因此，了解虚拟机的运作并不是一般开发人员必须掌握的知识。
然而，凡事都具备两面性。随着Java技术的不断发展，它被应用于越来越多的领域之中。其中一些领域，如电力、金融、通信等，对程序的性能、稳定性和可扩展性方面都有极高的要求。一个程序很可能在10个人同时使用时完全正常，但是在10000个人同时使用时就会变慢、死锁甚至崩溃。毫无疑问，要满足10000个人同时使用需要更高性能的物理硬件，但是在绝大多数情况下，提升硬件效能无法等比例地提升程序的性能和并发能力，有时甚至可能对程序的性能没有任何改善作用。这里面有Java虚拟机的原因：为了达到为所有硬件提供一致的虚拟平台的目的，牺牲了一些硬件相关的性能特性。更重要的是人为原因：开发人员如果不了解虚拟机的一些技术特性的运行原理，就无法写出最适合虚拟机运行和可自优化的代码。
其实，目前商用的高性能Java虚拟机都提供了相当多的优化特性和调节手段，用于满足应用程序在实际生产环境中对性能和稳定性的要求。如果只是为了入门学习，让程序在自己的机器上正常运行，那么这些特性可以说是可有可无的；如果用于生产环境，尤其是企业级应用开发中，就迫切需要开发人员中至少有一部分人对虚拟机的特性及调节方法具有很清晰的认识，所以在Java开发体系中，对架构师、系统调优师、高级程序员等角色的需求一直都非常大。学习虚拟机中各种自动运作的特性的原理也成为了Java程序员成长道路上必然会接触到的一课。通过本书，读者可以以一种相对轻松的方式学习虚拟机的运作原理，对Java程序员的成长也有较大的帮助。本书读者对象（1） 使用Java技术体系的中、高级开发人员
Java虚拟机作为中、高级开发人员必须修炼的知识，有着较高的学习门槛，本书可作为学习虚拟机的优秀教材。
（2） 系统调优师
系统调优师是近几年才兴起的职业，本书中的大量案例、代码和调优实战将会对系统调优师的日常工作有直接的帮助。
（3） 系统架构师
保障系统高效、稳定和可伸缩是系统架构师的主要职责之一，而这与虚拟机的运作密不可分，本书可以作为他们设计应用系统底层框架的参考资料。如何阅读本书本书一共分为五个部分：走近Java、自动内存管理机制、虚拟机执行子系统、程序编译与代码优化、高效并发。各个部分基本上是相互独立的，没有必然的前后依赖关系，读者可以从任何一个感兴趣的专题开始阅读，但是每个部分中的各个章节间有先后顺序。
本书并不假设读者在Java领域具备很专业的技术水平，因此在保证逻辑准确的前提下，尽量用通俗的语言和案例讲述虚拟机中与开发关系最为密切的内容。当然学习虚拟机技术本身就需要读者有一定的技术基础，且本书的读者定位是中、高级程序员，因此本书假设读者自己了解一些常用的开发框架、Java API和Java语法等基础知识。
语言约定
本书在语言和技术上有如下的约定：
本书中提到HotSpot虚拟机、JRockit虚拟机、WebLogic服务器等产品的所有者时，仍然使用Sun和BEA公司的名称。实际上BEA和Sun分别于2008年和2010年被Oracle公司收购，现在已经不存在这两个商标了，但是毫无疑问它们都是对Java领域做出过卓越贡献的、值得程序员纪念的公司。
JDK从1.5版本开始，在官方的正式文档与宣传资料中已经不再使用类似“JDK 1.5”的名称，只有在程序员内部使用的开发版本号 （Developer Version，例如java -version的输出）中才继续沿用1.5、1.6和1.7的版本号，而公开版本号（Product Version）则改为JDK 5、JDK 6和JDK 7的命名方式。为了行文一致，本书所有场合统一采用开发版本号的命名方式。
由于版面关系，本书中的许多示例代码都没有遵循最优的代码编写风格，如使用的流没有关闭流等，请读者在阅读时注意这一点。
如果没有特殊说明，本书中所有的讨论都是以Sun JDK 1.6为技术平台的。不过如果有某个特性在各个版本间的变化较大，一般都会说明它在各个版本间的差异。内容特色第一部分　走近Java
本书的第一部分为后文的讲解建立了良好的基础。尽管了解Java技术的来龙去脉，以及编译自己的OpenJDK对于读者理解Java虚拟机并不是必需的，但是这些准备过程可以为走近Java技术和Java虚拟机提供很好的引导。第一部分只有第1章：
第1章　介绍了Java技术体系的过去、现在和未来的发展趋势，并介绍了如何独立编译一个OpenJDK 7。
第二部分　自动内存管理机制
因为程序员把内存控制的权力交给了Java虚拟机，所以可以在编码的时候享受自动内存管理的诸多优势，不过也正因为这个原因，一旦出现内存泄漏和溢出方面的问题，如果不了解虚拟机是怎样使用内存的，那么排查错误将会成为一项异常艰难的工作。第二部分包括第2～5章：
第2章　讲解了虚拟机中的内存是如何划分的，哪部分区域、什么样的代码和操作可能导致内存溢出异常，并讲解了各个区域出现内存溢出异常的常见原因。
第3章　分析了垃圾收集的算法和JDK 1.6中提供的几款垃圾收集器的特点及运作原理，通过代码实例验证了Java虚拟机中的自动内存分配及回收的主要规则。
第4章　介绍了随JDK发布的6个命令行工具与2个可视化的故障处理工具的使用方法。
第5章　与读者分享了几个比较有代表性的实际案例，还准备了一个所有开发人员都能“亲身实战”的练习，读者可通过实践来获得故障处理和调优的经验。
第三部分　虚拟机执行子系统
执行子系统是虚拟机中必不可少的组成部分，了解了虚拟机如何执行程序，才能写出更优秀的代码。第三部分包括第6～9章：
第6章　讲解了Class文件结构中的各个组成部分，以及每个部分的定义、数据结构和使用方法，以实战的方式演示了Class的数据是如何存储和访问的。
第7章　介绍了在类加载过程的“加载”、“验证”、“准备”、“解析”和“初始化”这五个阶段中虚拟机分别执行了哪些动作，还介绍了类加载器的工作原理及其对虚拟机的意义。
第8章　分析了虚拟机在执行代码时如何找到正确的方法，如何执行方法内的字节码，以及执行代码时涉及的内存结构。
第9章　通过四个类加载及执行子系统的案例，分享了使用类加载器和处理字节码的一些值得欣赏和借鉴的思路，并通过一个实战练习来加深对前面理论知识的理解。
第四部分　程序编译与代码优化
Java程序从源码编译成字节码和从字节码编译成本地机器码的这两个过程，合并起来其实就等同于一个传统编译器所执行的编译过程。第四部分包括第10和11章：
第10章　分析了Java语言中的泛型、自动装箱拆箱、条件编译等多种语法糖的前因后果，并通过实战案例演示了如何使用插入式注解处理器来实现一个检查程序命名规范的编译器插件。
第11章　讲解了虚拟机的热点探测方法、HotSpot的即时编译器、编译触发条件，以及如何从虚拟机外部观察和分析JIT编译的数据和结果。此外，还讲解了几种常见的编译期优化技术。
第五部分　高效并发
Java语言和虚拟机提供了原生的、完善的多线程支持，使得它天生就适合开发多线程并发的应用程序。不过我们不能期望系统来完成所有与并发相关的处理，了解并发的内幕也是一个高级程序员不可缺少的课程。第五部分包括第12和13章：
第12章　讲解了虚拟机的Java内存模型的结构和操作，以及原子性、可见性和有序性在Java内存模型中的体现，介绍了先行发生原则及使用，还讲解了线程在Java语言中是如何实现的。
第13章　介绍了线程安全所涉及的概念和分类、同步实现的方式以及虚拟机的底层运作原理，并且还介绍了虚拟机实现高效并发所采取的一系列锁优化措施。
目录
前　言
致　谢
第一部分　走近Java
第1章　走近Java / 2
1.1　概述 / 2
1.2　Java技术体系 / 3
1.3　Java发展史 / 5
1.4　展望Java技术的未来 / 9
1.4.1　模块化 / 9
1.4.2　混合语言 / 9
1.4.3　多核并行 / 11
1.4.4　进一步丰富语法 / 12
1.4.5　64位虚拟机 / 13
1.5　实战：自己编译JDK / 13
1.5.1　获取JDK源码 / 13
1.5.2　系统需求 / 14
1.5.3　构建编译环境 / 15
1.5.4　准备依赖项 / 17
1.5.5　进行编译 / 18
1.6　本章小结 / 21
第二部分　自动内存管理机制
第2章　Java内存区域与内存溢出异常 / 24
2.1　概述 / 24
2.2　运行时数据区域 / 25
2.2.1　程序计数器 / 25
2.2.2　Java虚拟机栈 / 26
2.2.3　本地方法栈 / 27
2.2.4　Java堆 / 27
2.2.5　方法区 / 28
2.2.6　运行时常量池 / 29
2.2.7　直接内存 / 29
2.3　对象访问 / 30
2.4　实战：OutOfMemoryError异常 / 32
2.4.1　Java堆溢出 / 32
2.4.2　虚拟机栈和本地方法栈溢出 / 35
2.4.3　运行时常量池溢出 / 38
2.4.4　方法区溢出 / 39
2.4.5　本机直接内存溢出 / 41
2.5　本章小结 / 42
第3章　垃圾收集器与内存分配策略 / 43
3.1　概述 / 43
3.2　对象已死？ / 44
3.2.1　引用计数算法 / 44
3.2.2　根搜索算法 / 46
3.2.3　再谈引用 / 47
3.2.4　生存还是死亡？ / 48
3.2.5　回收方法区 / 50
3.3　垃圾收集算法 / 51
3.3.1　标记 -清除算法 / 51
3.3.2　复制算法 / 52
3.3.3　标记-整理算法 / 54
3.3.4　分代收集算法 / 54
3.4　垃圾收集器 / 55
3.4.1　Serial收集器 / 56
3.4.2　ParNew收集器 / 57
3.4.3　Parallel Scavenge收集器 / 59
3.4.4　Serial Old收集器 / 60
3.4.5　Parallel Old收集器 / 61
3.4.6　CMS收集器 / 61
3.4.7　G1收集器 / 64
3.4.8　垃圾收集器参数总结 / 64
3.5　内存分配与回收策略 / 65
3.5.1　对象优先在Eden分配 / 66
3.5.2　大对象直接进入老年代 / 68
3.5.3　长期存活的对象将进入老年代 / 69
3.5.4　动态对象年龄判定 / 71
3.5.5　空间分配担保 / 73
3.6　本章小结 / 75
第4章　虚拟机性能监控与故障处理工具 / 76
4.1　概述 / 76
4.2　JDK的命令行工具 / 76
4.2.1　jps：虚拟机进程状况工具 / 79
4.2.2　jstat：虚拟机统计信息监视工具 / 80
4.2.3　jinfo：Java配置信息工具 / 82
4.2.4　jmap：Java内存映像工具 / 82
4.2.5　jhat：虚拟机堆转储快照分析工具 / 84
4.2.6　jstack：Java堆栈跟踪工具 / 85
4.3　JDK的可视化工具 / 87
4.3.1　JConsole：Java监视与管理控制台 / 88
4.3.2　VisualVM：多合一故障处理工具 / 96
4.4　本章小结 / 105
第5章　调优案例分析与实战 / 106
5.1　概述 / 106
5.2　案例分析 / 106
5.2.1　高性能硬件上的程序部署策略 / 106
5.2.2　集群间同步导致的内存溢出 / 109
5.2.3　堆外内存导致的溢出错误 / 110
5.2.4　外部命令导致系统缓慢 / 112
5.2.5　服务器JVM进程崩溃 / 113
5.3　实战：Eclipse运行速度调优 / 114
5.3.1　调优前的程序运行状态 / 114
5.3.2　升级JDK 1.6的性能变化及兼容问题 / 117
5.3.3　编译时间和类加载时间的优化 / 122
5.3.4　调整内存设置控制垃圾收集频率 / 126
5.3.5　选择收集器降低延迟 / 130
5.4　本章小结 / 133
第三部分　虚拟机执行子系统
第6章　类文件结构 / 136
6.1　概述 / 136
6.2　无关性的基石 / 136
6.3　Class类文件的结构 / 138
6.3.1　魔数与Class文件的版本 / 139
6.3.2　常量池 / 141
6.3.3　访问标志 / 147
6.3.4　类索引、父类索引与接口索引集合 / 148
6.3.5　字段表集合 / 149
6.3.6　方法表集合 / 153
6.3.7　属性表集合 / 155
6.4　Class文件结构的发展 / 168
6.5　本章小结 / 170
第7章　虚拟机类加载机制 / 171
7.1　概述 / 171
7.2　类加载的时机 / 172
7.3　类加载的过程 / 176
7.3.1　加载 / 176
7.3.2　验证 / 178
7.3.3　准备 / 181
7.3.4　解析 / 182
7.3.5　初始化 / 186
7.4　类加载器 / 189
7.4.1　类与类加载器 / 189
7.4.2　双亲委派模型 / 191
7.4.3　破坏双亲委派模型 / 194
7.5　本章小结 / 197
第8章　虚拟机字节码执行引擎 / 198
8.1　概述 / 198
8.2　运行时栈帧结构 / 199
8.2.1　局部变量表 / 199
8.2.2　操作数栈 / 204
8.2.3　动态连接 / 206
8.2.4　方法返回地址 / 206
8.2.5　附加信息 / 207
8.3　方法调用 / 207
8.3.1　解析 / 207
8.3.2　分派 / 209
8.4　基于栈的字节码解释执行引擎 / 221
8.4.1　解释执行 / 221
8.4.2　基于栈的指令集与基于寄存器的指令集 / 223
8.4.3　基于栈的解释器执行过程 / 224
8.5　本章小结 / 230
第9章　类加载及执行子系统的案例与实战 / 231
9.1　概述 / 231
9.2　案例分析 / 231
9.2.1　Tomcat：正统的类加载器架构 / 232
9.2.2　OSGi：灵活的类加载器架构 / 235
9.2.3　字节码生成技术与动态代理的实现 / 238
9.2.4　Retrotranslator：跨越JDK版本 / 242
9.3　实战：自己动手实现远程执行功能 / 246
9.3.1　目标 / 246
9.3.2　思路 / 247
9.3.3　实现 / 248
9.3.4　验证 / 255
9.4　本章小结 / 256
第四部分　程序编译与代码优化
第10章　早期（编译期）优化 / 258
10.1　概述 / 258
10.2　Javac编译器 / 259
10.2.1　Javac的源码与调试 / 259
10.2.2　解析与填充符号表 / 262
10.2.3　注解处理器 / 264
10.2.4　语义分析与字节码生成 / 264
10.3　Java语法糖的味道 / 268
10.3.1　泛型与类型擦除 / 268
10.3.2　自动装箱、拆箱与遍历循环 / 273
10.3.3　条件编译 / 275
10.4　实战：插入式注解处理器 / 276
10.4.1　实战目标 / 276
10.4.2　代码实现 / 277
10.4.3　运行与测试 / 284
10.4.4　其他应用案例 / 286
10.5　本章小结 / 286
第11章　晚期（运行期）优化 / 287
11.1　概述 / 287
11.2　HotSpot虚拟机内的即时编译器 / 288
11.2.1　解释器与编译器 / 288
11.2.2　编译对象与触发条件 / 291
11.2.3　编译过程 / 294
11.2.4　查看与分析即时编译结果 / 297
11.3　编译优化技术 / 301
11.3.1　优化技术概览 / 301
11.3.2　公共子表达式消除 / 305
11.3.3　数组边界检查消除 / 307
11.3.4　方法内联 / 307
11.3.5　逃逸分析 / 309
11.4　Java与C/C++的编译器对比 / 311
11.5　本章小结 / 313
第五部分　高效并发
第12章　Java内存模型与线程 / 316
12.1　概述 / 316
12.2　硬件的效率与一致性 / 317
12.3　Java内存模型 / 318
12.3.1　主内存与工作内存 / 319
12.3.2　内存间交互操作 / 320
12.3.3　对于volatile型变量的特殊规则 / 322
12.3.4　对于long和double型变量的特殊规则 / 327
12.3.5　原子性、可见性与有序性 / 328
12.3.6　先行发生原则 / 330
12.4　Java与线程 / 333
12.4.1　线程的实现 / 333
12.4.2　Java线程调度 / 337
12.4.3　状态转换 / 339
12.5　本章小结 / 341
第13章　线程安全与锁优化 / 342
13.1　概述 / 342
13.2　线程安全 / 343
13.2.1　Java语言中的线程安全 / 343
13.2.2　线程安全的实现方法 / 348
13.3　锁优化 / 356
13.3.1　自旋锁与自适应自旋 / 356
13.3.2　锁消除 / 357
13.3.3　锁粗化 / 358
13.3.4　轻量级锁 / 358
13.3.5　偏向锁 / 361
13.4　本章小结 / 362
附录A　Java虚拟机家族 / 363
附录B　虚拟机字节码指令表 / 366
附录C　HotSpot虚拟机主要参数表 / 372
附录D　对象查询语言（OQL）简介 / 376
附录E　JDK历史版本轨迹 / 383