GC-分代收集算法

垃圾收集器:跟踪存活对象,回收其他垃圾。GC算法主要通过标记,复制,整理,清除来进行垃圾的回收。
标记:记录所有存活的对象,通过标记可达对象来进行区分。
垃圾收集的两种算法主要是:分代收集算法,分区收集算法。

分代收集算法

这种算法将根据对象存活时间来区分,在JVM中分为新生代,老年代,永久代(在java 8之后取消永久代,变为元空间)。
新生代:每次进行垃圾收集都会发现大量垃圾,采用的是“标记-复制”算法。
新生代中又分为Eden区、SurvivorFrom区、SurvivorTo区。
Eden:是内存中的一个区域,用来分配新创建的对象,又有多个线程同时创 建多个对象,Eden 区被划分为多个线程本地缓冲分配区 (Thread Local Allocation Buffer, 简称 TLAB)。对象通过TLAB进行缓冲区划分,如果TLAB被分配完,再进行Eden共享,如果Eden也无法分配,触发年轻代垃圾收集器,如果还是没有空间,将会将其转入老年代。
SurvivorFrom, SurvivorTo:存活区,是Eden旁边的两块区域,叫做from区和for区。两者必定有一个是空的。空的存放收集到的对象,所有的存活对象都会被复制到for区,然后进行多次复制,里面的对象在进行多次复制并且没被清除的话,会被转入老年代(根据标记存活次数进行确定 ‐XX:+MaxTenuringThreshold=x,x是存活次数,默认设置最大数:15)。
老年代:因为对象存活率高,存活次数多。没有额外空间对它进行分配担保, 就必须采用“标记—清理”或“标记—整理”算法。
通过标志位(marked bit),标记所有垃圾收集器对象. 删除所有没标记对象 整理老年代空间中的内容,方法是将所有的存活对象复制,从老年代空间开始的地方,依次存放。老年代 GC必须明确地进行整理,以避免内存碎片过多。
垃圾收集器
垃圾收集器
由上图可以看出:
年轻代和老年代的串行 GC(Serial GC) (单线程,工作时停止所有线程)
年轻代和老年代的并行 GC(Parallel GC) (多线程,工作时停止所有线程)
年轻代的并行 GC(Parallel New) (停止其他线程) + 老年代的 CMS(Concurrent Mark and Sweep)(和其他线程抢占cpu时间)
G1, 负责回收年轻代和老年代(区域划分和优先级区域回收机制)

Serial 垃圾收集器
针对年轻代:最基本的垃圾收集器,使用复制算法。单线程垃圾收集器,运行时只会使用一个cpu或者线程,并且会停止其他线程或CPU的运行,对于单个县城或者cpu来说简单高效。是java 虚拟机运行在 Client 模式下默认的新生代垃圾收集器。
ParNew垃圾收集器
针对年轻代:多线程年轻代垃圾收集器,是Serial的多线程版本,但是同样会暂停其他线程,ParNew 收集器默认开启和 CPU 数目相同的线程数,是很多 java虚拟机运行在 Server 模式下新生代的默认垃圾收集器。
Parallel Scavenge 收集器
Parallel Scavenge 收集器也是一个新生代垃圾收集器,同样使用复制算法并且暂停所有的线程,也是一个多线程的垃圾收集器,它重点关注的是程序达到一个可控制的吞吐量。
因为对系统资源的有效使用,能达到更高的吞吐量: 在 GC期间, 所有 CPU 内核都在并行清理垃圾, 所以暂停时间更短 。在两次 GC周期的间隔期, 没有 GC线程在运行,不会消耗任何系统资源。
主要适用于在后台运算而不需要太多交互的任务。自适应调节策略也是 ParallelScavenge 收集器与 ParNew 收集器的一个重要区别。
Serial Old 垃圾收集器
Serial 老年代版本,针对老年代使用的垃圾收集器,使用的是“标记-清除-整理”算法,单线程,同样暂停所有工作中的线程,是运行在 Client 默认的 java 虚拟机默认的年老代垃圾收集器。
ParOld垃圾收集器
Parallel Scavenge老年代版本。使用的是“标记-清除-整理”算法,关注的是老年代的程序吞吐量。为了达到大量的程序吞吐量,新生代 Parallel Scavenge可以和parallelOld一起进行工作。
parallelNew可以和parallelOld
新生代 Parallel Scavenge使用多线程的复制算法,将垃圾进行清理,之后parallelOld再进行标记清理算法进行年老代垃圾收集。
CMS 收集器(多线程标记清除算法)
CMS 的官方名称为 “Mostly Concurrent Mark and Sweep Garbage Collector”(主要并发­标记­清除­垃圾收集器)。采用并发清理,年轻代使用“复制”算法,老年代使用“标记清理”算法。CMS 的设计目标是避免在老年代垃圾收集时出现长时间的卡顿。主要通过两种手段来达成此目标。:
第一, 不对老年代进行整理, 而是使用空闲列表(free­lists)来管理内存空间的回收。
第二, 在 mark­and­sweep (标记­清除) 阶段的大部分工作和应用线程一起并发执行。
CMS主要经历下面四个阶段:初始标记-并发标记-重新标记-并发清理。
初始标记:此阶段的目标是标记老年代中所有存活的对象,仍然需要暂停所有的工作线程。 包括 GC Roots 的直接引用, 以及由年轻代中存活对象所引用的对象。 后者也非常重要, 因为老年代是独立进行回收。
并发标记:进行 GC Roots 跟踪的过程,和用户线程一起工作,不需要暂停工作线程。垃圾收集器遍历老年代, 标记所有的存活对象, 从前一阶段找到的 root 根开始算起。
重新标记:为了修正在并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,仍然需要暂停所有的工作线程。
并发清理:清除 GC Roots 不可达对象,和用户线程一起工作,不需要暂停工作线程。由于耗时最长的并发标记和并发清除过程中,垃圾收集线程可以和用户现在一起并发工作,所以总体上来看CMS 收集器的内存回收和用户线程是一起并发地执行。工作原理:
cms垃圾回收过程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值