引言:

  前面的文章提到,Heap包括了PSYoungGen、ParOldGen、Metaspace。JVM 在进行GC时,并非每次都对上面三个内存区域一起回收的,大部分时候回收的都是新生代。由于新生代和老年代的内存空间大小不同以及对象存活率不同,所以针对不同区域JVM采用了不同的GC,不同的GC是通过不同的算法实现的。在Jdk8中,按照回收区域的不同,把GC分为工作在新生代的普通GC(minor GC)和工作在堆全局空间的全局GC(Full  GC)。

  由于新生代和老年代占比空间为1:2,且采用了不同的算法,所以minor GC 的速度要比Full GC快很多。

一、复制算法

  HotSpot 把新生代分为三个部分:Eden区和两个Survivor区(From区和To区),默认比例8:1:1。对象创建时会被放在Eden区,当Eden区触发GC(minor GC),GC会对Eden和Survivor区进行垃圾回收,幸存下来的独享会被 “复制” 到Survivor1区(To区),然后清空Eden和From区,最后将To和From交换,让刚才被清空的From作新的To区,让刚才保存对象的To区作新的From区,以保证下一次GC可以扫描到这些对象。这个过程中涉及到了一个 “复制” 的操作,就是 “复制算法” 的产物。顺带一提:当一个对象在多次GC后依然无法被回收,在From区和To区来回复制,没复制一次“年龄”加1,一旦“年龄”达到MaxTenuringThreshold的值(默认为15)就会被移动到老年代。

  为了方便描述,这里将minor GC的扫描区域(Eden、From)简称为From区,因为这两块区域的共同特点就是在复制幸存对象到To区后会被清空,唯一的区别就是Eden用来保存第一次new出来的对象,而From区保存的则是经过若干次GC后任然幸存的对象。

  整个流程如下图所示:

  

  红色为幸存对象,黄色为被GC回收的对象,绿色表示闲置空间。当触发GC后,Eden区和From区的幸存对象会被复制到To区,然后清空Eden区和From区,最后将From区和To区对调,以保证下一次GC的正常工作流程。这些内容在前面介绍堆参数时也有提及,这里不再赘述。需要补充的是 “复制算法” 的优缺点:

  优点:1、由于“复制算法”采用了复制—清空的方法,所以不会导致内存空间的碎片化

  缺点:1、由于复制算法需要另外的空间来 “周转” 这些幸存的对象,所以内存消耗比较大。

     2、如果存在“极端情况”,比如大量的对象循环引用而导致无法回收的幸存对象占比很大,假设为80%,那么就需要将这些数量庞大的对象都复制一遍,并将所有的引用地址重置一遍,这回耗费比较多的时间。所以复制算法的最佳工作环境就是这一块的对象存活率比较低。

二、标记清除

  这是GC在老年代中的工作方式,标记清除算法分为两个阶段:标记阶段和清除阶段。

  

  这种算法虽然不需要多余的内存空间 “周转” 对象,但是会导致内存碎片化。于是便引出了标记压缩算法

三、标记压缩

  标记压缩其实就是在标记清除后加了一个 “压缩” 操作,将分散的数据压缩到一块连续的内存空间。就是慢,但慢工出细活。

  

四、更加优秀的选择

  针对老年的GC,标记清除和标记压缩都不完美,最好的方式是组合使用,在多次使用标记清除后进行一次压缩。总的来说四种方式没有孰优孰劣,只有谁更合适。总结一下就是:

执行效率(算法的时间复杂度):复制算法>标记清除>标记压缩

内存整齐度:复制算法=标记压缩>标记清除

内存利用率:标记清除=标记压缩>复制算法

  在Java9默认采用了G1垃圾回收器,采用了时间复杂度和空间利用率都非常出色的算法。

GC四大算法的更多相关文章

  1. 【JVM】垃圾回收的四大算法

    GC垃圾回收 JVM大部分时候回收的都是新生代(伊甸区+幸存0区+幸存1区).按照回收的区域可以分成两种类型:Minor GC和Full GC(MajorGC). Minor GC:只针对新生代区域的 ...

  2. 初步了解JVM第三篇(堆和GC回收算法)

    在<初步了解JVM第一篇>和<初步了解JVM第二篇>中,分别介绍了: 类加载器:负责加载*.class文件,将字节码内容加载到内存中.其中类加载器的类型有如下:执行引擎:负责解 ...

  3. 《垃圾回收的算法与实现》——GC复制算法

    基本概念 GC复制算法将堆分成From和To两个内存块,当From被占满时GC将From中的存活对象复制到To中,同时将From和To交换. 通过递归遍历GC root(即采用深度优先)复制存活对象, ...

  4. 【转载】GC基本算法及C++GC机制

    原文: GC基本算法及C++GC机制 阅读目录 前言 基本概念 有向可达图与根集 三种基本的垃圾收集算法及其改进算法 1.引用计数算法 2. Mark & Sweep 算法 3. 节点复制算法 ...

  5. GC回收算法

    GC回收算法 https://www.cnblogs.com/missOfAugust/p/9528166.html Java语言引入了垃圾回收机制,让C++语言中令人头疼的内存管理问题迎刃而解,使得 ...

  6. GC回收算法--当女友跟你提分手!

    Java语言引入了垃圾回收机制,让C++语言中令人头疼的内存管理问题迎刃而解,使得我们Java狗每天开开心心地创建对象而不用管对象死活,这些都是Java的垃圾回收机制带来的好处.但是Java的垃圾回收 ...

  7. GC回收算法&&GC回收器

    GC回收算法 什么是垃圾? 类比日常生活中,如果一个东西经常没被使用,那么就可以说是垃圾. 同理,如果一个对象不可能再被引用,那么这个对象就是垃圾,应该被回收. 垃圾:不可能再被引用的对象. fina ...

  8. java虚拟机学习总结之GC回收算法与GC收集器

    GC回收算法 1.标记清除算法分为标记阶段和清除阶段标记阶段:通过特定的判断方式找出无用的对象实例并将其标记清除阶段:将已标记的对象所占用的内存回收缺点:运行多次以后容易产生空间碎片,当需要一整段连续 ...

  9. JVM内存模型及GC回收算法

    该篇博客主要对JVM内存模型以及GC回收算法以自己的理解和认识做以记录. 内存模型 GC垃圾回收 1.内存模型 从上图可以看出,JVM分为 方法区,虚拟机栈,本地方法栈,堆,计数器 5个区域.其中最为 ...

随机推荐

  1. JAVAWEB第一节课的课后思考

    第一开发一个网站需要的一些技术 至少熟悉一种建站程序.(html,javascript等等)对空间和域名的知识有一定的了解.有一些美工基础(例如ps设计等等).对编程有一些了解.HTML的代码知识基本 ...

  2. Vue中的循环以及修改差值表达式

    0828自我总结 一.Vue中的循环 v-for 常见的4总情况 #第一种 <div v-for="item in items"></div> #第二种 & ...

  3. RF作用与目的

    robotframework自动化原理:通过ride工具编写脚本,加载指定的UI测试库,再通过pybot程序去运行指定脚本,调用浏览器驱动,打开浏览器,操作浏览器页面元素,达到模拟用户操作的行为 为什 ...

  4. 攻防世界(XCTF)WEB(进阶区)write up(一)

      cat ics-05 ics-06 lottery Cat XCTF 4th-WHCTF-2017 输入域名  输入普通域名无果  输入127.0.0.1返回了ping码的结果 有可能是命令执行 ...

  5. opencv::自定义线性滤波

    卷积概念 常见算子 自定义卷积模糊 卷积概念 1.卷积是图像处理中一个操作,是kernel在图像的每个像素上的操作. 2.Kernel本质上一个固定大小的矩阵数组,其中心点称为锚点(anchor po ...

  6. 00jmeter安装相关

    1.官网下载安装包:http://jmeter.apache.org/ 下载最新版本: 2.将下载后的zip文件解压 3. jdk与jmeter的环境变量配置(以下变量如果没有则新建,如果已存在则直接 ...

  7. ESP8266开发之旅 网络篇⑬ SPIFFS——ESP8266 SPIFFS文件系统

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  8. 通过一个生活中的案例场景,揭开并发包底层AQS的神秘面纱

    本文导读 生活中案例场景介绍 联想到 AQS 到底是什么 AQS 的设计初衷 揭秘 AQS 底层实现 最后的总结 当你在学习某一个技能的时候,是否曾有过这样的感觉,就是同一个技能点学完了之后,过了一段 ...

  9. 初级开发者也能码出专业炫酷的3D地图吗?

    好看的3D地图搭建出来,一定是要能为开发者所用与业务系统开发中才能真正地体现价值.基因于此,CityBuilder建立了与ThingJS的通道——直转ThingJS代码,支持将配置完成的3D地图一键转 ...

  10. kafka里的一些管理脚本

    kafka-server-start脚本 ------启动kafka server kafka-server-stop脚本 ------关闭kafka server kafka-topics脚本 -- ...