垃圾收集器回收种类

垃圾收集器是垃圾回收算法的具体实现

串行垃圾回收器(Serial)

它为单线程环境设计且只使用一个线程进行垃圾回收,会暂停用户线程

(并行垃圾回收器)Parallel

多个垃圾收集器并行工作,此时用户线程是暂停的

并发垃圾回收器(CMS)

用户线程和垃圾收集线程同时执行(不一定是并行,可能是交替执行,不需要停顿用户线程)

G1垃圾回收器

G1垃圾回收器将堆内存分割成不同的区域然后并发的对其进行垃圾回收

七种垃圾收集器

Serial

Serial,最基本最老的收集器。其存在的主要问题是"Stop The World",即在垃圾回收的时候,必须要暂停所有的其他工作线程,直到收集完成。此外在工作的时候,其垃圾收集线程是单线程的。

ParNew

ParNew 其实就是 Serial 的多线程版本。其除了垃圾收集线程是多线程意外,其他功能与 Serial 一样,如收集算法、Stop The World 的特性、对象分配规则、回收策略等。

Parallel Scavenge

Parallel Scavenge 大多数特性与 ParNew 相似,其最主要的特点是其设计的目标是达到一个 可控制的吞吐量,所谓吞吐量就是 CPU 用于运行用户代码的时间和 CPU 总消耗时间的比值,即 吞吐量 = 运行用户代码时间 / (运行用户代码时间 + 垃圾收集时间)。高吞吐量意味着高效率地利用 CPU 时间,尽快完成程序计算任务,适合在后台运算而不需要太多交互的任务。

Serial Old

其是 Serial 的老年代版本,其他特性和 Serial 类似,不多赘述。

Parallel Old

其是 Parallel Scavenge 的老年代版本,适合跟 Parallel Scavenge 一起组成一个 吞吐量优先 的收集组合。

CMS

CMS的全称为 Concurrent Mark Sweep,其设计理念是获取最短回收停顿时间。其回收步骤为

  1. 初始标记
  2. 并发标记
  3. 重新标记
  4. 并发清除

初始标记是简单标记一下 GC Roots 能关联到的对象,因此速度很快。并发标记则需要进行 GC Roots Tracing,重新标记是为了修正在并发标记期间因用户程序继续运行而导致标记产生变动的对象,最终执行并发清除过程。

在收集过程中,只有初始标记和重新标记需要 Stop The World, 耗时较多。而耗时较多的并发标记和并发清除阶段都是可以和用户线程一起执行的,因此其可以大大减少停顿时间。

从CMS的执行模型中,我们也可以看到其拥有以下缺点。

首先我们看到整个 GC 在第 4步是并发清除的,那么在清除过程中就会产生 浮动垃圾 ,因为此时用户线程还在继续执行,因此必然会产生新的垃圾,而这些垃圾因为已经错过了这次的标记,就需要等到下次才能被回收。

此外也正是因为并发清除的原因, JVM 需要为用户运行过程产生的对象预留空间,那么这个度又该如何把握呢?如果预留的少了,就会出现 "Concurrent Mode Failure" 失败,此时 JVM 会启用后备方案:Serial Old,那么就会导致较长时间的停顿。如果预留的多了,那么就会频繁地进行 Full GC,影响性能。

并且因为清除阶段采用的是并发清除,那么用户线程因为在执行的原因,就必然只能采用 标记-清除算法 ,这样就会导致产生大量的内存碎片。

最后因为 CMS 是一个针对并发模型的实现,那么在并发阶段就必然会占用 CPU 时间,这就必然会导致应用程序变慢,因为这个是所有针对并发进行设计的程序都会有的问题。

G1

Garbage-First 算法的核心观念是将堆划分为多个大小相等的独立区域——Region(还保留着新生代和老年代,但其不再是物理隔离的,而是一系列region的集合)。

在程序运行过程中,G1 会维护一个 优先级列表,里面记录着各个 Region 的垃圾堆积价值(回收所获得大小和回收所需时间的比值),这样在每次回收的时候,根据 允许的回收时间,优先回收价值最大的 Region,通过这样,我们的 GC 时间就是可预测的。

但是听着将堆划分为多个 Region 很简单,在实际情况下,我们该如何保证 Region 以及其中对象的独立性呢?

实际上,Region 不可能是独立的,因为一个对象分配到这个 Region 上,但其可能会被堆上的任一个引用所关联。这样在进行可达性分析的时候,难道意味着要进行 全堆扫描 吗?如果这样的话,性能又该如何保证呢?

因此 G1 使用了 Remembered Set 来避免这一现象。在程序对 Reference 类型数据进行写操作时,其会产生一个 Write Barrier 暂时中断写操作,来检查 Reference 引用对象是否处于不同的 Region 中,如果是,则通过 CardTable 将相关引用信息记录到对象所属 Region 的 Remembered Set 中,这样在进行内存回收,可达性分析的时候通过 Remembered Set 则可以保证不对全堆扫描也不会有遗漏。

G1 详细的执行流程如下:

  1. 初始标记
  2. 并发标记
  3. 最终标记
  4. 筛选回收

粗略来看,G1 的前 3个步骤和 CMS 十分类似。但其内部还是有些不一样。

首先是初始标记阶段,G1 和 CMS 类似,也只是标记一下 GC Roots 能直接关联到的对象,但其还修改了 TAMS(Next Top at Mark Start)的值,让下一阶段并发标记时,用户线程可以正确的在可用 Region 中创建对象。并发标记阶段和 CMS 一样,但将这段时间对象变化记录存储在 Remembered Set Log 中;在最终标记阶段,将 Remembered Set Log 合并到 Remembered Set 中,最终在筛选回收阶段首先对 各个 Region 的价值进行排序,然后根据用户设置的回收时间来制定回收计划。

CMS和G1的对比:

G1是为了替代CMS而存在的。在以下方面表现的更出色:

G1是一个有整理内存过程的垃圾收集器,不会产生很多的内存碎片

G1的STW更可控,G1在停顿时间尚增加了预测机制,用户可以指定期望停顿时间

※G1底层原理

对象特别大直接在分给多个区域来装 :humongous区域 (如果一个对象占用的空间超过了分区容量50%以上,G1收集器就认为这是个巨型对象,这些对象默认直接会被分配到老年代,但是如果他是一个但其存在的巨型对象,G1就会划分一个humongous区域来进行存放,如果一个H区放不下,就会去找连续的H区,但是找不到就会不得不进行FullGC)

在非G1收集器是如何装大对象得?

G1算法将堆分为诺干个区域,它们任然属于分代收集器

这些区域的一部分包含新生代,新生代的垃圾收集依然采用暂停所有应用线程的方式,将存活对象拷贝到老年代或者Survivor空间。

这些区域一部分包含老年代,G1收集器通过将对象从一个区域复制到另外一个区域,完成了清理工作。这就意味着,在正常处理过程中,G1完成了堆的压缩,至少是部分堆的压缩,这样也就不会有CMS内存碎片化的问题了

回收后

查看默认的垃圾回收器

jdk8

-XX:+PrintCommandLineFlags -version

Jdk8的默认垃圾收集器

Paraller收集器

-XX:+UseParallelGC

Jdk8如何设置垃圾收集器

如何选择垃圾收集器

参考博客: https://www.cnblogs.com/JRookie/p/11272394.html

垃圾收集器回收种类 以及七种垃圾收集器相关推荐

  1. jvm七种垃圾收集器

    JVM_七种垃圾收集器介绍 本文中的垃圾收集器研究背景为:HotSpot+JDK7 一.垃圾收集器概述 如上图所示,垃圾回收算法一共有7个,3个属于年轻代.三个属于年老代,G1属于横跨年轻代和年老代的 ...

  2. JVM之垃圾收集器回收种类

    JVM之垃圾收集器回收种类 目录 面试常见问题 串行并行并发G1四大垃圾回收方式 如何查看默认的垃圾收集器 JVM默认的垃圾收集器有哪些 GC之7大垃圾收集器详解 1. 面试常见问题 GC垃圾回收算法 ...

  3. 七种垃圾收集器和垃圾回收、分代收集、GCROOTS相关概念、GC如何判断一个对象可以被回收

    文章目录 垃圾收集器概述 垃圾回收算法 1)标记-清除算法(Mark-Sweep)(DVM 使用的算法) 2)复制算法(Copying) 3)标记-整理算法(Mark-Compact) 4)分代收集( ...

  4. JVM学习----七种垃圾收集器(GC)

    文章目录 GC垃圾收集器 七种经典的垃圾回收器 查看默认垃圾收集器 新生代 Serial垃圾收集器(单线程. 复制算法) ParNew 垃圾收集器 (Serial的多线程版本. 复制算法) Paral ...

  5. Java 的七种垃圾收集器

    了解 Java 中的内存管理. 用 C 或 C++ 这样的编程语言写一个应用时,需要编写代码来销毁内存中不再需要的对象.当应用程序扩展得越来越复杂时,未使用对象被忽略释放的可能性就越大.这会导致内存泄 ...

  6. JVM常见的七种垃圾收集器的简单比较

    1.Serial收集器曾经是虚拟机新生代收集的唯一选择,是一个单线程的收集器,在进行收集垃圾时,必须stop the world,它是虚拟机运行在Client模式下的默认新生代收集器. 2.Seria ...

  7. Java——七种垃圾收集器+JDK11最新ZGC

    JDK1.8之前的堆内存示意图: 从上图可以看出堆内存的分为新生代.老年代和永久代.新生代又被进一步分为:Eden 区+Survior1 区+Survior2 区.值得注意的是,在 JDK 1.8中移 ...

  8. 擦窗机器人出发点_一种擦窗机器人初步设计与实现

    龙源期刊网 http://www.qikan.com.cn 一种擦窗机器人初步设计与实现 作者:朱彪彪 徐军委 于阳光 安春桥 来源:<智富时代> 2019 年第 08 期 [摘 要]设计 ...

  9. 【Android 逆向】类加载器 ClassLoader ( Android 的八种类加载器 | ClassLoader | BaseDexClassLoader | DexClassLoader )

    文章目录 一.Android 类加载器 1.ClassLoader 抽象类 2.BootClassLoader 3.BaseDexClassLoader 4.PathClassLoader 5.Dex ...

最新文章

  1. mysql mediumtext longtext
  2. java线程callback,Java线程之异步回调(Callback)
  3. python输出数据到excel-python实现数据导出到excel的示例--普通格式
  4. asp.net 学习的一些地址
  5. VS2008编译汇编程序的问题
  6. 服务器-番外篇-搭建samba共享
  7. 2021.11.18
  8. SpringBoot使用Thymeleaf模板
  9. Rxjs 里 subscribeToArray 工具函数的详细分析
  10. SpringMVC常用的注解
  11. latex中插入eps图片方法与遇到xdvipdfmx:fatal: Image inclusion failed for XXX的错误
  12. 【AD】安装AD18教程
  13. 刨根笔记--由antd开始的jsx渲染学习路线
  14. 【2.5万字】详解 Python-docx 自动生成word图文报告
  15. vue之组件传值 爷到孙 provide inject
  16. 2022年K1刷第三方固件教程
  17. 翻译:理解特征工程(1)-连续数值数据
  18. Vue中使用svg(图片不显示问题)
  19. Steampipe的安装部署及简单使用(附带AWS CLI的安装与使用)
  20. Linux 如何查看 隐藏文件大小,某个文件大小,文件夹大小

热门文章

  1. 如何在把微信公众号生成链接
  2. 如何在公众号添加付费链接
  3. VMware下安装centos6.7的步骤
  4. 智安网络详解:零信任网络访问 (ZTNA)原理
  5. 疯狂android讲义目录
  6. MVC、MVP、MVVM:谁才是Android开发的终极之选?
  7. background-clip
  8. iPhone指环贴:你手机的防盗专家
  9. css强制换行和强制不换行
  10. 复习高数下册8-10章主要内容(简略版)