简述垃圾回收算法与垃圾回收器

垃圾收集算法算法

  1. 标记-清除算法
  2. 复制算法
  3. 标记-整理算法
  4. 分代收集算法

标记-清除算法:多线程

  • 首先标记出全部须要回收的对象,在标记完成后统一回收全部被标记的对象。
  • 它的主要不足有两个:一个是效率问题,标记和清除两个过程的效率都不高;另外一个是空间问题,标记清除以后会产生大量不连续的内存碎片,致使以后程序运行时须要分配比较大,没法找到足够大连续的空间。

复制算法:并发

  • 为了解决效率问题,它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另一块上面,而后再把已使用过的内存空间一次清理掉。
  • 代价是将内存缩小为了原来的一半

标记-整理算法:性能

  • 为解决对象存活率高时进行较多的复制操做,以及浪费一半内存空间就须要有额外的空间进行分配担保
  • 标记过程仍然与“标记-清除”算法同样,让全部存活的对象都向一端移动,而后直接清理掉端边界之外的内存。

分代收集算法:线程

  • 在新生代中,每次垃圾收集时都发现有大批对象死去,只有少许存活,那就选用复制算法,只须要付出少许存活对象的复制成本就能够完成收集。
  • 在老年代中,由于对象存活率高、没有额外空间对它进行分配担保,就必须使用“标记—清理”或者“标记—整理”算法来进行回收。

2.垃圾收集器3d

若是两个垃圾收集器之间存在连线,说明能够搭配使用。对象

1.Serial收集器blog

 

特性:简单而高效,该收集器没有线程交互的开销,能够获取最高的单线程收集效率。排序

基本原理:单线程,在进行垃圾收集时,必须暂停其余全部的工做线程,直到它收集结束。内存

使用场景:在Client模式下,分配给虚拟机管理的内存通常来讲不会很大,收集几十兆甚至一两百兆的新生代,停顿时间彻底能够接受。

2.ParNew收集器

特性:除了Serial收集器之外,只有ParNew收集器能够CMS收集器配合。

基本原理:Serial收集器的多线程版本

使用场景:在Server模式下的虚拟机中首选的新生代收集器。

3.Parallel Savenge收集器(吞吐量优先)

特性:缩短停顿时间是以牺牲吞吐量和新生代空间来换取的:新生代空间变小,垃圾回收变得频繁,致使吞吐量降低。

        能够经过一个开关参数打开 GC 自适应的调节策略(GC Ergonomics),就不须要手工指定新生代的大小(-Xmn)、Eden 和 Survivor 区的比例、晋升老年代对象年龄等细节参数了。虚拟机会根据当前系统的运行状况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量。

基本原理:与 ParNew 同样是多线程收集器,其它收集器目标是尽量缩短垃圾收集时用户线程的停顿时间,而它的目标是达到一个可控制的吞吐量,所以它被称为“吞吐量优先”收集器。

使用场景:停顿时间越短就越适合须要与用户交互的程序,良好的响应速度能提高用户体验。而高吞吐量则能够高效率地利用 CPU 时间,尽快完成程序的运算任务,适合在后台运算而不须要太多交互的任务。

4.Serial Old 收集器

基本原理:Serial Old是Serial收集器的老年代版本,单线程收集器,使用“标记-整理”算法

使用场景:主要意义也是在于给Client模式下的虚拟机使用。若是在Server模式下,那么它主要还有两大用途:一种用途是在JDK 1.5以及以前的版本中与Parallel Scavenge收集器搭配使用,另外一种用途就是做为CMS收集器的后备预案,在并发收集发生用。

5.Parallel Old收集器

特性:除了Serial收集器之外,只有ParNew收集器能够CMS收集器配合。

基本原理:Parallel Old是Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理”算法。

使用场景:在注重吞吐量以及CPU资源敏感的场合,均可以优先考虑Parallel Scavenge加Parallel Old收集器。

6.CMS收集器

  • 初始标记:仅仅只是标记一下GC Roots能直接关联到的对象,速度很快,须要停顿。
  • 并发标记:进行GC RootsTracing的过程
  • 从新标记:是为了修正并发标记期间因用户程序继续运做而致使标记产生变更的那一部分对象的标记记录,须要停顿。
  • 并发清除

        因为整个过程当中耗时最长的并发标记和并发清除过程收集器线程均可以与用户线程一块儿工做,因此,从整体上来讲,CMS收集器的内存回收过程是与用户线程一块儿并发执行的。

有如下3个明显的缺点:

  • CMS收集器对CPU资源很是敏感。在并发阶段,它虽然不会致使用户线程停顿,可是会由于占用了一部分线程(或者说CPU资源)而致使应用程序变慢,总吞吐量会下降。
  • 没法处理浮动垃圾,可能出现 Concurrent Mode Failure。浮动垃圾是指并发清除阶段因为用户线程继续运行而产生的垃圾,这部分垃圾只能到下一次 GC 时才能进行回收。因为浮动垃圾的存在,所以须要预留出一部份内存,意味着 CMS 收集不能像其它收集器那样等待老年代快满的时候再回收。若是预留的内存不够存放浮动垃圾,就会出现 Concurrent Mode Failure,这时虚拟机将临时启用 Serial Old 来替代 CMS。
  • CMS是一款基于“标记—清除”算法实现的收集器。空间碎片过多时,将会给大对象分配带来很大麻烦,每每会出现老年代还有很大空间剩余,可是没法找到足够大的连续空间来分配当前对象,不得不提早触发一次Full GC。

7.G1收集器

G1(Garbage-First),它是一款面向服务端应用的垃圾收集器,在多 CPU 和大内存的场景下有很好的性能。HotSpot 开发团队赋予它的使命是将来能够替换掉 CMS 收集器。

堆被分为新生代和老年代,其它收集器进行收集的范围都是整个新生代或者老年代,而 G1 能够直接对新生代和老年代一块儿回收。

G1 把堆划分红多个大小相等的独立区域(Region),新生代和老年代再也不物理隔离。

        经过引入 Region 的概念,从而将原来的一整块内存空间划分红多个的小空间,使得每一个小空间能够单独进行垃圾回收。这种划分方法带来了很大的灵活性,使得可预测的停顿时间模型成为可能。经过记录每一个 Region 垃圾回收时间以及回收所得到的空间(这两个值是经过过去回收的经验得到),并维护一个优先列表,每次根据容许的收集时间,优先回收价值最大的 Region。

        每一个 Region 都有一个 Remembered Set,用来记录该 Region 对象的引用对象所在的 Region。经过使用 Remembered Set,在作可达性分析的时候就能够避免全堆扫描。

若是不计算维护 Remembered Set 的操做,G1 收集器的运做大体可划分为如下几个步骤:

  • 初始标记
  • 并发标记
  • 最终标记:为了修正在并发标记期间因用户程序继续运做而致使标记产生变更的那一部分标记记录,虚拟机将这段时间对象变化记录在线程的 Remembered Set Logs 里面,最终标记阶段须要把 Remembered Set Logs 的数据合并到 Remembered Set 中。这阶段须要停顿线程,可是可并行执行。
  • 筛选回收:首先对各个 Region 中的回收价值和成本进行排序,根据用户所指望的 GC 停顿时间来制定回收计划。此阶段其实也能够作到与用户程序一块儿并发执行,可是由于只回收一部分 Region,时间是用户可控制的,并且停顿用户线程将大幅度提升收集效率。

具有以下特色:

  • 空间整合:总体来看是基于“标记 - 整理”算法实现的收集器,从局部(两个 Region 之间)上来看是基于“复制”算法实现的,这意味着运行期间不会产生内存空间碎片。
  • 可预测的停顿:能让使用者明确指定在一个长度为 M 毫秒的时间片断内,消耗在 GC 上的时间不得超过 N 毫秒。
相关文章
相关标签/搜索