2.6.GC分代收集算法 VS 分区收集算法
2.6.1.分代收集算法
- 当前主流VM垃圾收集都采用分代收集算法(Generational Collection),这种算法会根据对象存活周期的不同将内存化为几块,如jvm中的新生代,老年代,永久代,这样就可以根据哥年代特点分别采用最适当的GC算法。
2.6.1.1.在新生代-复制算法
- 每次垃圾收集都能发现大批对象已死,只有少量的存活对象,因此选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。
2.6.1.2.在老年代-标记整理算法
- 因为对象存活率高,没有额外空间对它进行分配担保,就必须采用“标记-清理”或者“标记-整理”算法来进行回收,不必进行内存复制,且直接腾出空闲内存。
2.6.2.分区收集算法
- 分区算法将整个堆空间划分为连续的不同小区间,每个小区间独立使用,独立回收,这样做的好处是可以控制一次回收多少个小区间,根据合理的回收若干个小区间(而不是整个堆),从而减少一个GC所产生的停顿。
2.7.GC垃圾收集器
- Java堆内存被划分为新生代和老年代两个部分,新生代主要使用复制和标记-清除垃圾回收算法,老年代主要使用标记-整理垃圾回收算法,因此Java虚拟机中针对新生代和老年代分别提供了多种不同的垃圾算法收集器,jdk1.6中sun HotSpot虚拟机的垃圾收集器如下:
2.7.1.Serial垃圾收集器(单线程,复制算法)
- Serial(英文连续)是最基本垃圾收集器,使用复制算法,曾经是jdk1.3.1之前新生代唯一的垃圾收集器,Serial(英文连续)是一个单线程的收集器,它不但只会使用一个CPU或一条线程去完成垃圾收集工作,并且在进行垃圾收集的同时,必须暂停其他所有的工作线程,知道垃圾收集结束,Serial(英文连续)垃圾收集器虽然在收集垃圾过程中需要暂停其他所有的工作线程,但是它简单高效,对于限定单个CPU环境来说,没有线程交互的开销,可以获得最高的单线程垃圾回收效率,因此Serial(英文连续)垃圾收集器依然是Java虚拟机运行在Client迷失下默认的新生代垃圾收集器
2.7.2.ParNew 垃圾收集器(Serial+多线程)
- ParNew 垃圾收集器(Serial+多线程)其实是Serial收集器的多线程版本,也使用了复制算法,除了使用多线程进行垃圾收集之外,其余的行为和Serial收集器完成相同,ParNew 垃圾收集器(Serial+多线程)在垃圾收集过程中同样也要暂停其他的工作线程。ParNew 垃圾收集器(Serial+多线程)默认开启和CPU数目相同的线程数,可以通过-XX:ParalleGCThreads参数来限制垃圾收集器的线程数。ParNew 垃圾收集器(Serial+多线程)虽然是除了多线程外和Serial收集器几乎完全一样,但是ParNew 垃圾收集器(Serial+多线程)是很多Java虚拟机运行在Service模式下新生代的默认垃圾收集器。
2.7.3.Parallel Scavenge 收集器(多线程复制算法、高效)
- Parallel Scavenge 收集器(多线程复制算法、高效)也是一个新生代垃圾收集器,同样使用复制算法,也是一个多线程的垃圾收集器,它的重点关注的是程序达到一个可控制的的吞吐量(Thoughput,CPU 用于运行用户代码的时间/CPU 总消耗时间,即吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)),高吞吐量可以高效率的利用CPU时间,尽快的完成程序的运算任务,主要适用于在后台运算而不需要太多交互任务,自适应调节策略也是ParallelScavenge 收集器与 ParNew 收集器的一个
重要区别。