上一篇我们介绍了常见的垃圾回收算法,不同的算法各有各的优缺点,在JVM中并不是单纯的使用某一种算法进行垃圾回收,而是将不同的垃圾回收算法包装在不同的垃圾回收器当中,用户可以根据自身的需求,使用不同的垃圾回收器,以便让自己的java程序性能到达最佳。

在介绍垃圾回收器之前,我们先回顾一下java堆的结构。

堆内存回顾

java堆内存结构包括:新生代和老年代,其中新生代由一个伊甸区和2个幸存区组成,2个幸存区是大小相同,完全对称的,没有任何差别。我们把它们称为S0区和S1区,也可以称为from区和to区。

JVM的垃圾回收主要是针对以上堆空间的垃圾回收,当然其实也会针对元数据区(永久区)进行垃圾回收,在此我们主要介绍对堆空间的垃圾回收。

下面我们介绍几种垃圾回收器:

串行收集器

顾名思义,串行收集器就是使用单线程进行垃圾回收。对新生代的回收使用复制算法,对老年代使用标记压缩算法,这也和我们上一篇介绍的算法优势是相吻合的。

串行收集器是最古老最稳定的收集器,尽管它是串行回收,回收时间较长,但其稳定性是优于其他回收器的,综合来说是一个不错的选择。要使用串行收集器,可以在启动配置时加上以下参数:

-XX:+UseSerialGC

串行回收器的执行流程如下所示:

执行垃圾回收时,应用程序线程暂停,GC线程开始(开始垃圾回收),垃圾回收完成后,应用程序线程继续执行。注意:在GC线程运行过程中使用单线程进行串行回收。

并行回收器

并行回收器你可能已经猜到就是使用多线程并行回收,不过这里需要注意的是,针对新生代和老年代,是否都使用并行,有不同的回收器选择:

1、 ParNew回收器

这个回收器只针对新生代进行并发回收,老年代依然使用串行回收。回收算法依然和串行回收一样,新生代使用复制算法,老年代使用标记压缩算法。在多核条件下,它的性能显然优于串行回收器,如果要使用这种回收器,可以在启动参数中配置:

-XX:+UseParNewGC

如果要进一步指定并发的线程数,可以配置一下参数:

-XX:ParallelGCThreads

ParNew回收器的流程如下图所示:

在进行垃圾回收时应用程序线程依然被暂停,GC线程并行开始执行垃圾回收,垃圾回收完成后,应用程序线程继续执行。

2、 Parallel回收器

依然是并行回收器,但这种回收器有两种配置,一种类似于ParNEW:新生代使用并行回收、老年代使用串行回收。它与ParNew的不同在于它在设计目标上更重视吞吐量,可以认为在相同的条件下它比ParNew更优。要使用这种回收器可以在启动程序中配置:

-XX:+UseParallelGC

Parallel回收器另外一种配置则不同于ParNew,对于新生代和老年代均适应并行回收,要使用这种回收器可以在启动程序中配置:

XX:+UseParallelOldGC

Parallel回收器的流程和ParNew的流程是一致的:

在进行回收时,应用程序暂停,GC使用多线程并发回收,回收完成后应用程序线程继续运行。

CMS回收器

CMS回收器: Concurrent Mark Sweep,并发标记清除。注意这里注意两个词:并发、标记清除。

并发表示它可以与应用程序并发执行、交替执行;标记清除表示这种回收器不是使用的是标记压缩算法,这和前面介绍的串行回收器和并发回收器有所不同。需要注意的是CMS回收器是一种针对老年代的回收器,不对新生代产生作用。这种回收器优点在于减少了应用程序停顿的时间,因为它不需要应用程序完成暂定等待垃圾回收,而是与垃圾回收并发执行。要执行这种垃圾回收器可以在启动参数中配置:

-XX:+UseConcMarkSweepGC

CMS回收机运行机制非常复杂,我们简单的将他的运行流程分为以下几步:

初始标记

标记从GC Root可以直接可达的对象;

并发标记(和应用程序线程一起)

主要标记过程,标记全部对象;

重新标记

由于并发标记时,用户线程依然运行,因此在正式清理前,再做依次重新标记,进行修正。

并发清除(和用户线程一起)

基于标记结果,直接清理对象。

流程如下图所示:

从上图可以看到标记过程分三步:初始标记、并发标记、重新标记,并发标记是最主要的标记过程,而这个过程是并发执行的,可以与应用程序线程同时进行,初始标记和重新标记虽然不能和应用程序并发执行,但这两个过程标记速度快,时间短,所以对应用程序不会产生太大的影响。最后并发清除的过程,也是和应用程序同时进行的,避免了应用程序的停顿。

CMS的优点显而易见,就是减少了应用程序的停顿时间,让回收线程和应用程序线程可以并发执行。但它也不是完美的,从他的运行机制可以看出,因为它不像其他回收器一样集中一段时间对垃圾进行回收,并且在回收时应用程序还是运行,因此它的回收并不彻底。这也导致了CMS回收的频率相较其他回收器要高,频繁的回收将影响应用程序的吞吐量。

G1回收器

G1回收器是jdk1.7以后推出的回收器,试图取代CMS回收器。

不同于其他的回收器、G1将堆空间划分成了互相独立的区块。每块区域既有可能属于老年代、也有可能是新生代,并且每类区域空间可以是不连续的(对比CMS的老年代和新生代都必须是连续的)。这种将老年代区划分成多块的理念源于:当并发后台线程寻找可回收的对象时、有些区块包含可回收的对象要比其他区块多很多。虽然在清理这些区块时G1仍然需要暂停应用线程、但可以用相对较少的时间优先回收包含垃圾最多区块。这也是为什么G1命名为Garbage First的原因:第一时间处理垃圾最多的区块。要使用G1回收器需要在启动是配置以下参数:

-XX:+UseG1GC

G1相对CMS回收器来说优点在于:

1、因为划分了很多区块,回收时减小了内存碎片的产生;

2、G1适用于新生代和老年代,而CMS只适用于老年代。

小结

本文简要介绍了JVM中的垃圾回收器,主要包括串行回收器、并行回收器以及CMS回收器、G1回收器。他们各自都有优缺点,通常来说你需要根据你的业务,进行基于垃圾回收器的性能测试,然后再做选择。下面给出配置回收器时,经常使用的参数:

-XX:+UseSerialGC:在新生代和老年代使用串行收集器

-XX:+UseParNewGC:在新生代使用并行收集器

-XX:+UseParallelGC :新生代使用并行回收收集器,更加关注吞吐量

-XX:+UseParallelOldGC:老年代使用并行回收收集器

-XX:ParallelGCThreads:设置用于垃圾回收的线程数

-XX:+UseConcMarkSweepGC:新生代使用并行收集器,老年代使用CMS+串行收集器

-XX:ParallelCMSThreads:设定CMS的线程数量

-XX:+UseG1GC:启用G1垃圾回收器

JVM学习--(五)垃圾回收器的更多相关文章

  1. JVM学习——G1垃圾回收器(学习过程)

    JVM学习--G1垃圾回收器 把这个跨时代的垃圾回收器的笔记独立出来. 新生代:适用复制算法 老年代:适用标记清除.标记整理算法 二娃本来看G1的时候觉得比较枯燥,但是后来总结完之后告诉我说,一定要慢 ...

  2. JVM学习笔记——垃圾回收篇

    JVM学习笔记--垃圾回收篇 在本系列内容中我们会对JVM做一个系统的学习,本片将会介绍JVM的垃圾回收部分 我们会分为以下几部分进行介绍: 判断垃圾回收对象 垃圾回收算法 分代垃圾回收 垃圾回收器 ...

  3. 说一下 jvm 有哪些垃圾回收器?

    新生代收集器: SerialParNewParallel Scavenge 老年代收集器: Serial OldCMSParallel Old 堆内存垃圾收集器: G1 参考链接:JVM常见的垃圾回收 ...

  4. 【JVM】CMS垃圾回收器

    一.简介 Concurrent Mark Sweep,是一种以获取最短回收停顿时间为目标的收集器,尤其重视服务的响应速度. CMS是老年代垃圾回收器,基于标记-清除算法实现.新生代默认使用ParNew ...

  5. JVM有哪些垃圾回收器

    JVM 的垃圾回收器 目录 JVM 的垃圾回收器 经典垃圾收集器 Serial 收集器 ParNew 收集器 Parallel Scavenge 收集器 Serial Old 收集器 Parallel ...

  6. JVM学习--(四)垃圾回收算法

    我们都知道java语言与C语言最大的区别就是内存自动回收,那么JVM是怎么控制内存回收的,这篇文章将介绍JVM垃圾回收的几种算法,从而了解内存回收的基本原理. stop the world 在介绍垃圾 ...

  7. JVM学习记录-垃圾回收算法

    简述 因为各个平台的虚拟机的垃圾收集器的实现各有不同,所以只介绍几个常见的垃圾收集算法. JVM中常见的垃圾收集算法有以下四种: 标记-清除算法(Mark-Sweep). 复制算法(Copying). ...

  8. JVM几种垃圾回收器介绍

    整理自:http://www.cnblogs.com/lspz/p/6397649.html 一.如何回收? 1.1 垃圾收集算法: (1)标记-清除(Mark-Sweep)算法 这是最基础的算法,就 ...

  9. jvm中的垃圾回收器

    HotSpot JVM收集器 上面有7中收集器,分为两块,上面为新生代收集器,下面是老年代收集器.如果两个收集器之间存在连线,就说明它们可以搭配使用.Serial(串行GC)收集器 Serial收集器 ...

随机推荐

  1. 5.2、Android Studio截图

    Android Monitor允许你截取连接的设备或者虚拟机的屏幕,保存为PNG格式. 设备截图 1. 打开一个项目 2. 在设备或虚拟机中运行应用 3. 显示Android Monitor 4. 切 ...

  2. android orm持久层框架

    ; ; i < 2; i++) { )); ); h1.setWord("这是修改过的数据"); tv.setText(tv.getText() + "\n&quo ...

  3. UE4使用C++创建枚举变量适用于C++与蓝图

    这个月勉勉强强才写了一篇,都快月底了,都还没有写第二篇博客的冲动,证明这个月确实收获甚少,有点状态不佳,懒毒入骨啊.刚刚看了这个月其实已经写了三篇,然而事实是这博客还有另外一个人也在更新文章,博主并没 ...

  4. Hessian源码分析--总体架构

    Hessian是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能. 相比WebService,Hessian更简单.快捷.采用的是二进制RPC协议,因为采用的是二进制协 ...

  5. 【Unity Shaders】Lighting Models —— 光照模型之Lit Sphere

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  6. ROS_Kinetic_19 群机器人框架示例(micros swarm framework)

    ROS_Kinetic_19 群机器人框架示例(micros swarm framework) 官方网址:http://wiki.ros.org/micros_swarm_framework 这个包是 ...

  7. pig的udf编写

    http://www.cnblogs.com/anny-1980/p/3673569.html http://blog.csdn.net/ruishenh/article/details/120480 ...

  8. OpenCL异构计算资料收集

    Easy OpenCL with Python   原文  http://www.drdobbs.com/open-source/easy-opencl-with-python/240162614   ...

  9. oracle ebs应用产品安全性-数据访问权限集

    定义 数据访问权限集是一个重要的.必须设定的系统配置文件选项.对具有相同科目表.日历和期间类型的分类帐及其所有平衡段值或管理段值的定义读写权限,系统管理员将其分配至不同的责任以控制不同的责任对分类帐数 ...

  10. 开始ITGEGE教育社区的视频录制----嵌入式基础知识讲解

    从8月份开始,陆陆续续要对我的第一份兼职工作ITGEGE讲师做教学视频录制了,本人水平有限,我只讲一些开发在工作中的应用,其它细节的东西不做深究,毕竟本人工作经验和精力也有限,白天要上班,特别是最近又 ...