内容介绍
G1GC提出了不确定性Region,每个空闲Region不是为某个固定年代准备的,它是灵活的,需求驱动的,所以G1GC代表了先进性。 《深入理解JVM&G1GC》主要为学习Java语言的学生、初级程序员提供GC的使用参考建议及经验,着重介绍了G1GC。中国的软件开发行业已经有几十年了,从目前的行业发展来看,单纯的软件公司很难有发展,目前流行的云计算、物联网企业实际上是综合性IT技术的整合,这就需要有综合能力的程序员。《深入理解JVM&G1GC》作者力求做到知识的综合传播,而不是仅仅针对Java虚拟机和GC调优进行讲解,也力求每一章节都有实际的案例支撑。《深入理解JVM&G1GC》具体包括以下几方面:JVM基础知识、GC基础知识、G1GC的深入介绍、G1GC调优建议、JDK自带工具使用介绍等。 通读《深入理解JVM&G1GC》后,读者可以深入了解G1GC性能调优的许多主题及相关的综合性知识。读者也可以把《深入理解JVM&G1GC》作为参考,对于感兴趣的主题,直接跳到相应章节寻找答案。
关联推荐
★没有一招鲜似的调优秘籍或包罗万象的性能百科
★GC性能调优需要专门的知识技能才能解决
★解决的GC性能问题越多,技艺才会越精湛
★《深入理解JVM & G1 GC》不仅有技术实践,还有设计原理和目标
★让你深入掌握GC,积累更多技术与经验,
★更好地提升产品性能
目录
目 录 序 VII 前言 IX D1章 JVM & GC基础知识 1 1.1 引言 2 1.2 基本术语 3 1.2.1 Java相关术语 4 1.2.2 JVM/GC通用术语 24 1.2.3 G1涉及术语 56 1.3 本章小结 62 D2章 JVM & GC深入知识 63 2.1 Java虚拟机内存模型 64 2.1.1 程序计数器 65目 录
序 VII
前言 IX
D1章 JVM & GC基础知识 1
1.1 引言 2
1.2 基本术语 3
1.2.1 Java相关术语 4
1.2.2 JVM/GC通用术语 24
1.2.3 G1涉及术语 56
1.3 本章小结 62
D2章 JVM & GC深入知识 63
2.1 Java虚拟机内存模型 64
2.1.1 程序计数器 65
2.1.2 虚拟机栈 66
2.1.3 本地方法栈 72
2.1.4 Java堆 73
2.1.5 方法区 79
2.2 垃圾收集算法 82
2.2.1 引用计数法 82
2.2.2 根搜索算法 83
2.2.3 标记-清除算法(Mark-Sweep) 85
2.2.4 复制算法(Copying) 87
2.2.5 标记-压缩算法(Mark-Compact) 89
2.2.6 增量算法(Incremental Collecting) 90
2.2.7 分代收集算法(Generational Collecting) 91
2.3 Garbage Collection 92
2.3.1 GC概念 92
2.3.2 垃圾收集器分类 93
2.3.3 Serial收集器 94
2.3.4 ParNew收集器 96
2.3.5 Parallel收集器 99
2.3.6 CMS收集器 102
2.3.7 Garbage First(G1)GC 106
2.4 常见问题解析 112
2.4.1 jmap -heap或-histo不能用 112
2.4.2 YGC越来越慢 112
2.4.3 JavaYJ代去哪儿了 114
2.5 本章小结 116
D3章 G1 GC应用示例 117
3.1 范例程序 118
3.2 选项解释及应用 124
3.3 本章小结 166
D4章 深入G1 GC 167
4.1 G1 GC概念简述 168
4.1.1 背景知识 168
4.1.2 G1的垃圾回收机制 169
4.1.3 G1的区间设计灵感 169
4.2 G1 GC分代管理 172
4.2.1 年轻代 172
4.2.2 年轻代回收暂停 173
4.2.3 大对象区间 174
4.2.4 混合回收暂停 176
4.2.5 回收集合及其重要性 178
4.2.6 RSet及其重要性 178
4.2.7 并行标记循环 182
4.2.8 评估失败和完全回收 186
4.3 G1 GC使用场景 186
4.4 G1 GC论文原文翻译(部分) 187
4.4.1 开题 187
4.4.2 数据结构/机制 188
4.4.3 未来展望 190
4.5 本章小结 191
D5章 G1 GC性能优化方案 192
5.1 G1的年轻代回收 193
5.2 年轻代优化 203
5.3 并行标记阶段优化 205
5.4 混合回收阶段 207
5.4.1 初步介绍 207
5.4.2 深入介绍 208
5.5 如何避免出现GC失败 210
5.6 引用处理 211
5.6.1 观察引用处理 212
5.6.2 引用处理优化 213
5.7 本章小结 214
D6章 JVM诊断工具使用介绍 215
6.1 SA基础介绍 216
6.2 SA工具使用实践 217
6.2.1 如何启动SA 217
6.2.2 SA原理及使用介绍 222
6.3 其他工具介绍 231
6.3.1 GCHisto 231
6.3.2 JConsole 232
6.3.3 VisualVM 236
6.4 本章小结 238 显示全部信息
在线试读
2.2.1 引用计数法 引用计数法(Reference Counting)在GC执行垃圾回收之前,1先需要区分出内存中哪些是存活对象,哪些是已经死亡的对象。只有被标记为已经死亡的对象,GC才会在执行垃圾回收时,释放掉其所占用的内存空间,因此这个过程我们可以称为垃圾标记阶段。 引用计数器的实现很简单,对于一个对象A,只要有任何一个对象引用了A,则A的引用计数器就加1,D引用失效时,引用计数器就减1。只要对象A的引用计数器的值为0,则对象A就不可能再被使用。也就是说,引用计数器的实现只需要为每个对象配置一个整形的计数器即可。引用计数器算法的一大优势就是不用等待内存不够用的时候,才进行垃圾的回收,完全可以在赋值操作的同时检查计数器是否为0,如果是的话就可以立即回收。 但是引用计数器有一个严重的问题,即无法处理循环引用的情况。一个简单的循环引用问题的描述如下:有对象A和对象B,对象A中含有对象B的引用,对象B中含有对象A的引用。此时,对象A和对象B的引用计数器都不为0,但是在系统中却不存在任何D3个对象引用了A或B。也就是说,A和B是应该被回收的垃圾对象,但由于垃圾对象间相互引用,从而使垃圾回收器无法识别,引起内存泄漏。 如图2-6所示,构造了一个列表,将zui后一个元素的next属性指向D一个元素,即引用D一个元素,从而构成循环引用。这个时候如果将列表的头head赋值为null,此时列表的各个元素的计数器都不为0,同时也失去了对列表的引用控制,从而导致列表元素不能被回收。 引用计数器拥有一些特性,1先它需要单D的字段存储计数器,这样的做法增加了存储空间的开销。其次,每次赋值都需要更新计数器,这增加了时间开销。再者,垃圾对象便于辨识,只要计数器为0,就可作为垃圾回收。接下来它能方便及时地回收垃圾,没有延迟性。zui后不能解决循环引用的问题。正是由于zui后一条致命缺陷,导致在Java的垃圾回收器中没有使用这类算法。
2.2.1 引用计数法
引用计数法(Reference Counting)在GC执行垃圾回收之前,1先需要区分出内存中哪些是存活对象,哪些是已经死亡的对象。只有被标记为已经死亡的对象,GC才会在执行垃圾回收时,释放掉其所占用的内存空间,因此这个过程我们可以称为垃圾标记阶段。
引用计数器的实现很简单,对于一个对象A,只要有任何一个对象引用了A,则A的引用计数器就加1,D引用失效时,引用计数器就减1。只要对象A的引用计数器的值为0,则对象A就不可能再被使用。也就是说,引用计数器的实现只需要为每个对象配置一个整形的计数器即可。引用计数器算法的一大优势就是不用等待内存不够用的时候,才进行垃圾的回收,完全可以在赋值操作的同时检查计数器是否为0,如果是的话就可以立即回收。
但是引用计数器有一个严重的问题,即无法处理循环引用的情况。一个简单的循环引用问题的描述如下:有对象A和对象B,对象A中含有对象B的引用,对象B中含有对象A的引用。此时,对象A和对象B的引用计数器都不为0,但是在系统中却不存在任何D3个对象引用了A或B。也就是说,A和B是应该被回收的垃圾对象,但由于垃圾对象间相互引用,从而使垃圾回收器无法识别,引起内存泄漏。
如图2-6所示,构造了一个列表,将zui后一个元素的next属性指向D一个元素,即引用D一个元素,从而构成循环引用。这个时候如果将列表的头head赋值为null,此时列表的各个元素的计数器都不为0,同时也失去了对列表的引用控制,从而导致列表元素不能被回收。
引用计数器拥有一些特性,1先它需要单D的字段存储计数器,这样的做法增加了存储空间的开销。其次,每次赋值都需要更新计数器,这增加了时间开销。再者,垃圾对象便于辨识,只要计数器为0,就可作为垃圾回收。接下来它能方便及时地回收垃圾,没有延迟性。zui后不能解决循环引用的问题。正是由于zui后一条致命缺陷,导致在Java的垃圾回收器中没有使用这类算法。
2.2.2 根搜索算法
HotSpot和大部分JVM都是使用根搜索算法作为垃圾标记的算法实现。前面介绍过的引用计数算法尽管实现简单,执行效率也不错,但是该算法本身却存在一个较大的弊端,甚至会影响到垃圾标记的准确性。由于引用计数算法会为程序中的每一个对象都创建一个私有的引用计数器,D目标对象被其他存活对象引用时,引用计数器中的值则会加1,不再引用时便会减1,D引用计数器中的值为0的时候,就意味着该对象已经不再被任何存活对象引用,可以被标记为垃圾对象。采用这种方式看起来似乎没有任何问题,但是如果一些明显已经死亡了的对象尽管没有被任何的存活对象引用,但是它们彼此之间却存在相互引用时,引用计数器中的值则永远不会为0,这样便会导致GC在执行内存回收时永远无法释放掉这种无用对象所占用的内存空间,J有可能引发内存泄漏。
相对于引用计数算法而言,根搜索算法不仅同样具备实现简单和执行高效等特点,更重要的是该算法可以有效地解决在引用计数算法中一些已经死亡的对象因相互引用而导致的无法正确被标记的问题,防止内存泄漏的发生。简单来说,根搜索算法是以根对象集合为起始点,按照从上至下的方式搜索被根对象集合所连接的目标对象是否可达(使用根搜索算法后,内存中的存活对象都会被根对象集合直接或间接连接着),如果目标对象不可达,就意味着该对象已经死亡,便可以在instanceOopDesc[ HotSpot在C 代码中用instanceOopDesc类来表示Java对象,而该类继承oopDesc,所以HotSpot中的Java对象也自然拥有oopDesc所声明的头部。]的Mark World中将其标记为垃圾对象。在根搜索算法中,只有能够被根对象集合直接或者间接连接的对象才是存活对象。在HotSpot中,根对象集合中包含了5个元素,Java栈内的对象引用、本地方法栈内的对象引用、运行时常量池中的对象引用、方法区中类静态属性的对象引用以及与一个类对应的W一数据类型的Class对象。
显示全部信息
深入理解-JVM&G1 GC 下载 mobi epub pdf txt 电子书 格式