收集算法是内存回收的方法论,垃圾收集器是内存回收的具体实现。java
以上是 HotSpot 虚拟机中的 7 个垃圾收集器,连线表示垃圾收集器能够配合使用。算法
serial是新生代下的单线程收集器,它在进行垃圾收集时,必须暂停其余全部的工做线程,直到它收集结束。它是虚拟机运行在客户模式下的默认新生代垃圾收集器,它的优势是:简单高效,在单个 CPU 环境下,因为没有线程交互的开销,所以拥有最高的单线程收集效率。服务器
ParNew是serial的多线程版本,工做在新生代,是虚拟机在server模式下的首选新生代垃圾收集器,除了serial外只有它能和CMS收集器配合工做。多线程
ParNew在单CPU状况下,不会取得比serial好的收集效果。并发
paralle scavenge是新生代垃圾收集器,也是使用复制算法的收集器,又是并行的多线程收集器。它关注的点和其余收集器不一样,CMS等收集器关注的是尽量的缩短用户线程停顿时间,而它的目标则是达到一个可控制的吞吐率,所以paralle scavenge收集器也被称为“吞吐量优先”收集器。这里的吞吐量指 CPU 用于运行用户程序的时间占总时间的比值。性能
停顿时间越短就越适合须要与用户交互的程序,良好的响应速度能提高用户体验。而高吞吐量则能够高效率地利用 CPU 时间,尽快完成程序的运算任务,适合在后台运算而不须要太多交互的任务。线程
缩短停顿时间是以牺牲吞吐量和新生代空间来换取的:新生代空间变小,垃圾回收变得频繁,致使吞吐量降低。3d
能够经过一个开关参数打开 GC 自适应的调节策略(GC Ergonomics),就不须要手工指定新生代的大小(-Xmn)、Eden 和 Survivor 区的比例、晋升老年代对象年龄等细节参数了。虚拟机会根据当前系统的运行状况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量。server
serial old 是serial的老年代版本,它一样是单线程的收集器 ,使用标记-整理算法,这个收集器的主要意义也是个client模式下的虚拟机使用 ,若是实在server模式下使用,那它还有两种用途:对象
(1)配合paralle scavenge使用。
(2)做为CMS的后背预案,在并发收集Concurrent Mode Failure时使用。
Parallel Old 时paralle scavenge的老年代版本,使用多线程和标记-整理算法。
在对吞吐量以及CPU资源敏感的场合,优先考虑paralle scavenge和parallel old 收集器。
cms收集器是一种获取最短回收停顿时间为目标的收集器。cms是基于标记-清除算法实现的。它的运做过程分为4个部分。
(1)初始标记
(2)并发标记
(3)从新标记
(4)并发回收
初始标记,并发标记这两步仍然须要“stop the world”(中止用户线程工做),初始标记仅仅是标记一下GC Roots 能直接关联到的对象,速度很快,并发标记就是进行GC Roots 向下遍历的过程,速度比较慢,从新标记是为了修正并发标记期间因用户程序继续运做而致使标记产生变更的那一部分对象的标记。
并发标记和并发清除这两部分是耗时最长的,可是这两阶段均可以和用户线程一块儿工做,因此从整体上来讲,cms收集器的内存回收过程是与用户线程一块儿并发执行的。
优势:并发收集,低停顿。
缺点:
(1)虽然不会致使用户线程停顿,可是这是以牺牲了总的吞吐量为代价的,致使cpu利用率不高。
(2)不可以收集浮动垃圾致使full GC产生。因为cms并发清理阶段用户线程仍在执行,伴随着程序的运行还会有新的垃圾产生,这部分垃圾出如今标记以后,cms没法在当次处理他们,只能等到下次GC时在清理。这部分垃圾就称为浮动垃圾。
(3)因为采用标记-清除算法,产生大量的不连续内存碎片,对大对象的分配带来麻烦。每每会出现老年代还有很大空间,可是没法找到连续的空间来分配,不得不提早触发一次Full GC。
G1是一款面向服务器应用的垃圾回收器。HotSpot团队赋予它的使命是代替CMS垃圾收集器,与其余的GC收集器相比,G1具备如下特色:
(1)并行与并发:G1能充分利用多cpu的优点,来缩短stop the world停顿时间,部分其余的GC收集器本来要中止java线程执行GC动做,G1仍然能够经过并发让Java线程继续工做。
(2)分代收集:分代的概念在G1中仍然保留,可是G1能够不用和其余的收集器配合就能独立的管理整个GC堆,能采用不一样的方式去处理新建的对象和已经存活了一段时间的对象,熬过屡次GC的旧对象以获取更好的收集效果。
(3)空间整合:G1从总体上来看是基于标记-整理算法实现的收集器,从局部上来看(两个region)是基于复制算法实现的收集器,这两种算法都意味着G1在收集的过程当中不会产生内存碎片,收集可以提供规整的内存。
(4)可预测的停顿:G1相对于CMS的优点,G1除了追求低停顿时间外,还可以创建可预测的停顿时间模型,能明确让使用者指定在一个长度为M毫秒的时间片断内,消耗在垃圾收集上的时间不得超过N毫秒。
G1将整个Java堆分红多个大小相等的独立区域(region)虽然还保留老年代和新生代的概念,可是老年代和新生代不是物理隔离的了。
G1收集器之因此能创建可预测的停顿时间模型,是由于它有计划的避免在整个java堆进行垃圾回收,G1跟踪各个region里面的垃圾堆积的价值大小(回收所得到的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据收集时间,优先回收价值最大的区域,这种使用region划份内存空间及有优先级的回收方式,保证了G1收集器在有限的时间内能够获取可能高的收集效率。
每一个 Region 都有一个 Remembered Set,用来记录该 Region 对象的引用对象所在的 Region。经过使用 Remembered Set,在作可达性分析的时候就能够避免全堆扫描。
若是不维护remembered set,G1的运做分为如下几个步骤:
(1)初始标记
(2)并发标记
(3)最终标记
(4)筛选回收
初始标记阶段仅仅只是标记一下GC Roots能直接关联到的对象,而且须要修改TAMS的值,让下一阶段用户程序并发运行时,能在正确可用的region中建立对象,这个阶段须要停顿线程,可是停顿时间很短。
并发标记是从GC Roots开始从堆中对象进行可达性分析,找出存活的对象,这阶段耗时较长,可是能够与用户线程并发运行。
最终标记则是为了修正在并发标记期间因用户程序继续运行而致使标记产生变更的那一部分标记记录,虚拟机将这段时间对象变化记录在线程remembered set 中,这段须要停顿线程,可是能够并行进行。
筛选回收阶段首先对各个region的回收价值和成本进行排序,根据用户所指望的GC时间来指定回收计划。