轻松学习JVM(五)——垃圾回收器

上一篇我们介绍了常见的垃圾回收算法,不同的算法各有各的优缺点,在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一垃圾回收器

    上一篇我们介绍了常见的垃圾回收算法,不同的算法各有各的优缺点,在JVM中并不是单纯的使用某一种算法进行垃圾回收,而是将不同的垃圾回收算法包装在不同的垃圾回收器当中,用户可以根据自身的需求,使用不同的垃 ...

  2. 深入理解JVM(五) -- 垃圾回收算法

    上篇文章我们了解到哪些内存区域和哪些对象可以被回收,这篇文章我们就来了解一下具体的垃圾回收算法的思路,不讨论具体的实现. 一 最基础算法 标记-清除(Mark-Swap) 为什么说他是最基础的算法,因 ...

  3. 【JVM】垃圾回收器总结(2)——七种垃圾回收器类型

    七种垃圾回收器类型 GC的约定参数 DefNew——Default New Generation Tenured——Serial Old ParNew——Parallel New Generation ...

  4. JVM学习--(五)垃圾回收器

    上一篇我们介绍了常见的垃圾回收算法,不同的算法各有各的优缺点,在JVM中并不是单纯的使用某一种算法进行垃圾回收,而是将不同的垃圾回收算法包装在不同的垃圾回收器当中,用户可以根据自身的需求,使用不同的垃 ...

  5. 深入理解JVM一垃圾回收算法

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

  6. 深入理解JVM——关于垃圾回收

    关于垃圾回收 仿佛来自上海居委会大妈的灵魂拷问:“你是什么垃圾?” 不 今天我们要说的是JVM的垃圾回收 假如我是一个“人”类的“对象”,也和人的生命一样必有一死,可是“我真的还想再活500年~~”, ...

  7. JVM七大垃圾回收器下篇G1(Garbage First)

    G1回收器:区域化分代式 既然我们已经有了前面几个强大的GC,为什么还要发布Garbage First (G1)GC?  原因就在于应用程序所应对的业务越来越庞大.复杂,用户越来越多,没有GC就不能保 ...

  8. 面试官:说一下JVM常用垃圾回收器的特点、优劣势、使用场景和参数设置

    今天去看牙医,他问我年级轻轻牙齿怎么磨损这么严重?我说,没有人点赞的这些年,我都是咬着牙过来的. Java中的垃圾回收器几乎是面试中的必考点,无论是面试初级,中级还是高级,总免不了要问一问垃圾回收器的 ...

  9. JVM(3) 垃圾回收器与内存分配策略

    文章内容摘自:深入理解java虚拟机 第三章   对象已死? 1. 引用计数算法: 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器为0 ...

  10. 第三篇:jvm之垃圾回收器

    一.Serial收集器 新生代收集器,在垃圾回收时,必须暂停其他所有的工作线程.即Stop-The-World. 评价:老而无用,食之无味,弃之可惜. 二.ParNew收集器 新生代收集器,seria ...

随机推荐

  1. sharepoint 2013 使用SharePoint powershell 2013更改搜索server方法

    $hostA = Get-SPEnterpriseSearchServiceInstance -Identity "DevSearch2013" Start-SPEnterpris ...

  2. 导出Excel1 - 项目分解篇

    我们在全部的MIS系统(信息管理系统)中都能见到他.所以我们把这个通用功能提出来. 项目名称:车辆信息管理系统(中石化石炼) 项目负责人:xiaobin 项目时间:2006.12 - 2007.2 E ...

  3. 在Laravel中使用swoole来取代nginx作为http服务器

    1.是什么限制Laravel框架的速度? Laravel框架启动的时候需要加载很多文件,再加上其出了名的生态环境好,所以在开发过程中我们就会发现有非常多的已经造好的轮子,这也就使得Laravel的一次 ...

  4. mysql主从备份及常见问题处理

    1.mysql主从备份基本原理 mysql支持单向.异步复制,复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器.mysql复制基于主服务器在二进制日志中跟踪所有对数据库的更改(更新 ...

  5. Winform开发框架中工作流模块的业务表单开发

    在我们开发工作流的时候,往往需要设计到具体业务表单信息的编辑,有些是采用动态编辑的,有些则是在开发过程中处理的,各有各的优点,动态编辑的则方便维护各种各样的表单,但是数据的绑定及处理则比较麻烦,而自定 ...

  6. idea配置svn

    建议使用第二种方式比较简本人是使用第二种方式比较简单, 解决更新svn项目到本地报错的问题. ntelliJ IDEA 管理项目是十分的方便的,但有的小伙伴初次使用时,可能会遇到使用svn更新项目至本 ...

  7. 一个Web前端自学者的自述

    想来想去还是写下这篇文章,先说明,我精通JAVA编程语言和web前端常见的技术,个人是做JAVA的多,但是更加喜欢前端.因为我从高一开始接触JAVA,家父是黑马的JAVA讲师,自己对编程很热爱,在大学 ...

  8. selenium python自动化简明演示

    1.selenium安装: pip install -U selenium参考:https://pypi.python.org/pypi/selenium#downloads2.下载firefox驱动 ...

  9. python链接mysql

    1.安装MySQLdb MySQLdb 是用于Python链接Mysql数据库的接口,它实现了 Python 数据库 API 规范 V2.0,基于 MySQL C API 上建立的. 下载地址: ht ...

  10. BZOJ 4818 SDOI2017 序列计数

    刚出炉的省选题,还是山东的. 自古山东出数学和网络流,堪称思维的殿堂,比某地数据结构成风好多了. 废话不说上题解. 1.题面 求:n个数(顺序可更改),值域为[1,m],和为p的倍数,且这些数里面有质 ...