Java HotSpot虚拟机垃圾收集器

1.名词定义

OopMap数据结构:

可以把oopMap简单理解成是调试信息。在源代码里面每个变量都是有类型的,但是编译之后的代码就只有变量在栈上的位置了。oopMap就是一个附加的信息,告诉你栈上哪个位置本来是个什么东西。 这个信息是在JIT编译时跟机器码一起产生的。因为只有编译器知道源代码跟产生的代码的对应关系。 每个方法可能会有好几个oopMap,就是根据safepoint把一个方法的代码分成几段,每一段代码一个oopMap,作用域自然也仅限于这一段代码。 循环中引用多个对象,肯定会有多个变量,编译后占据栈上的多个位置。那这段代码的oopMap就会包含多条记录。

safePoint安全点:

每个被JIT编译过后的方法也会在一些特定的位置记录下OopMap,记录了执行到该方法的某条指令的时候,栈上和寄存器里哪些位置是引用。这样GC在扫描栈的时候就会查询这些OopMap就知道哪里是引用了。这些特定的位置主要在: 

1、循环的末尾 

2、方法临返回前 / 调用方法的call指令后 

3、可能抛异常的位置

这种位置被称为“安全点”(safepoint)。之所以要选择一些特定的位置来记录OopMap,是因为如果对每条指令(的位置)都记录OopMap的话,这些记录就会比较大,那么空间开销会显得不值得。选用一些比较关键的点来记录就能有效的缩小需要记录的数据量,但仍然能达到区分引用的目的。因为这样,HotSpot中GC不是在任意位置都可以进入,而只能在safepoint处进入。 

safe Region安全区域:

安全区域是指在一段代码片段中,引用关系不会发生变化。在这个区域中的任意地方开始GC都是安全的。可以把Safe Region看作扩展的Safepoint

2.垃圾收集器

1):新生代垃圾收集器(都使用复制算法)

——Serial:单线程垃圾收集器。在进行垃圾收集时会停掉所有的线程,等待垃圾收集完毕。优点:简单高效,在单cpu时效率较高,适合在Client模式下的虚拟机上运行。

——ParNew:Serial多线程垃圾收集器版本。在单线程中绝对不会有比Serial更高的效率。而在两个以上的cpu增加,他对于GC时系统资源的有效利用还是有好处的。

——Parallel Scavenge:吞吐量优先并发垃圾回收处理器,该收集器的目的是达到一个可控制的“吞吐量”。它提供了两个参数对吞吐量进行控制,一个是“控制最大垃圾收集停顿时间——-XX:MaxGCPauseMillis参数”,另一个是“直接设置吞吐量大小——-XX:GCTimeRatio”

2):老年代收集器

——Serial Old(MSC):采用“标记——整理”算法,是Serial收集器的老年代版本,这个收集器的意义也是在于给Client模式下的虚拟机使用

——Parallel Old:采用“标记——整理”算法,Parallel Scavenge老年代版本,在注重吞吐量与CPU资源的敏感场合,都优先考虑Parallel Scavenge+Parallel Old。

——CMS:采用“标记——清除”算法,是一种以获取最短回收停顿时间为目标的收集器,运作过程分为四个步骤:初始标记、并发标记、重新标记、并发清除。

缺点:(1)在Cpu较少的环境(4个以下)中由于对Cpu资源比较敏感,在并发回收垃圾对象时导致程序变慢。(2)无法处理浮动垃圾,由于CMS并发清理阶段用户线程还在不断的产生垃圾,无法在当前收集中处理掉他们,只好留到下一次GC时在清理。(2)由于“标记——清除”会造成不连续的内存,将会给大对象的分配造成麻烦。

3)G1收集器

G1收集器有以下特点:并发与并行,分代收集(逻辑上的)、空间整合(采用“标记——整理”算法)、可预测的停顿(能够让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不超过N毫秒)。

使用G1收集器时,Java堆的内存布局与其他收集器有很大差别,它将整个java内存分为多个大小相等的Region独立区域,新生代,老年代不是物理隔离的了,他们都是一部分Region的集合。

在反应停顿时间的软实时目标测试中G1碾压CMS,在吞吐量测试中两者差别不是很大。


你可能感兴趣的:(java基础知识整理)