引言

之前我们学习了 JVM 基本介绍 以及 什么样的对象需要被 GC ,今天就来学习一下 JVM 在判断出一个对象需要被 GC 会采用何种方式进行 GC。在学习 JVM 如何进行垃圾回收方法时,发现所谓的 JVM 垃圾回收思想和现实生活的场景有很多相似的地方。所以本文用餐厅回收餐桌的方式类比 JVM 垃圾回收算法,应该能帮助 JVM 学习的理解和记忆。

经典垃圾回收算

标记-清除(Mark-Sweep)

研发园开了家新餐厅,餐厅老板在考虑如何回收餐盘时首先使用了最简单的方式,那就是服务员在顾客用餐的过程中,不定时的观察餐厅,针对用完餐的顾客记录他们的位置(当然一般的服务员的脑海中自行处理),统一回收他们的餐具和餐盘。但是这种回收方式会有一个明显的问题,那就是回收后的餐厅座位,很有可能是不连续的。如果后续有同行的顾客(比如小情侣... ...)想坐在一起,那很可能找不到连续的座位。

复制算法(Copying)

为了解决餐厅座位碎片化的问题,餐厅的老板提出了一个大胆的想法,这是一个很会思考的老板。把餐厅的用餐区域分成两部分 A 厅和 B 厅,当对 A 厅中的餐桌做回收时,将 A 厅中还未用完餐的顾客,"请"到 B 厅去用餐,并且让这些顾客在 B 厅中拼桌用餐(为了餐位连续)。这样所有 A 厅中的位置都空余出来了,并且 B 厅中的用餐区域和未用餐区域都是连续的!简直是强迫症晚期。看似完美的解决了回收后餐位碎片化的问题。但是依然带来了其他的一些问题。

缺点:

  • 餐厅的运营区域是一个整体,现在只能同时对外开放 A 厅,运营空间变小了;

  • 当有很多顾客需要从 A 厅转移到 B 厅时,效率太低;

  • 用餐体验很差,不被骂娘才怪。

优点:

  • 不容易产生碎片

标记-整理算法(Mark-Compact)

当实行复制算法解决餐位回收后不连续的问题,餐厅的老板针对新问题又有了新想法,只要移动顾客就可以解决碎片化问题,为啥我要将餐厅分成两个的部分呢?毕竟那样不能最大效率的利用餐厅的用餐区域。创造性的提出了标记-整理算法,结合前面两中方法的优缺点,当餐厅准备回收餐位时,移动所有未用晚餐的顾客,并且让从餐厅的第一桌开始拼桌。这样保证后面的餐桌都是已经回收了餐盘的并且回收后的座位都是连续的。这样既提高了餐厅餐桌的利用率又保证了当有大量组团顾客进店用餐时,餐厅能够提供大量的连续餐桌(这个例子不恰当,如果真的碰到一个要让人不断移动形成空位的餐厅,你怕是要开喷了)。

分代收集(Generational Collection)

如果还是用开餐厅的方式来思考 JVM 的话,可以把分代回收看做餐厅针对不同顾客的等级推出的个性化服务。分代收集算法并没有新的思想,只是根据对象存活周期的不同将内存划分为几块,一般把 Java 堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中,大量的对象都是“朝生夕死”,每次垃圾回收时,都可以发现大量对象死去,所以针对新生代的垃圾回收一般选择复制算法。只需要复制少量存活对象就可以完成收集。针对老年代的垃圾回收,对象的存活时间较长,就必须使用标记-清除或者标记-整理算法来进行回收。

在新生代中,绝大多数的对象都是“朝生夕死”的,新生代并不需要按照 1:1 的比例划分内存空间,而是将内存分为一个较大的 Eden 空间和一个较小的 Survivor 空间,并将 Survivor 空间分成两个较小空间,分别是 From Space 和 ToSpace。每次使用 Eden 空间和其中的一块 Survivor 空间,当进行回收时,将该两块空间中还存活的对象复制到另一块 Survivor 空间中。Hotspot 虚拟机默认 Eden 和 Survivor 的大小比例是 8:1,也就是每次新生代可用内存空间为整个新生代容量的 90%。

这里很显然会有一个问题,理论上每次新生代 GC 都会回收绝大多数的对象,但是无法保证 GC 存活后的对象大学都不超过整个新生代的 10%。当 Survivor 空间的内存不够用是,就需要老年代做内存担保(分配担保策略,前边两篇文章有提过,读者可自行查阅)。同样用餐厅的理论来理解,你希望把 A 厅的顾客转移到 B 厅,但是 B 厅已经没有足够空间容纳所有顾客了,这时候可以选择将顾客安置在 VIP 包厢【老年代】。并且每次在新生代 GC 中存活的对象,其年龄就会 +1,默认情况下年龄达到 15 的对象会被转移到老年代。

这里也可以简单理解为我们给餐厅的忠实吃货办了张 VIP 卡... ...

所以,同学,办卡吗?办卡享五折优惠哈!

... ...

参考文档

《深入理解Java虚拟机》周志明 著

03 JVM 从入门到实战 | 简述垃圾回收算法的更多相关文章

  1. java虚拟机学习-JVM调优总结-新一代的垃圾回收算法(11)

    垃圾回收的瓶颈 传统分代垃圾回收方式,已经在一定程度上把垃圾回收给应用带来的负担降到了最小,把应用的吞吐量推到了一个极限.但是他无法解决的一个问题,就是Full GC所带来的应用暂停.在一些对实时性要 ...

  2. JVM知识(五):垃圾回收算法

    在介绍垃圾回收算法之前,我们需要先了解一个词“stop the world”,stop the world会在执行某一个垃圾回收算法的时候产生,JVM为了执行垃圾回收,会暂时java应用程序的执行,等 ...

  3. jvm 调优(2)垃圾回收算法

    可以从不同的的角度去划分垃圾回收算法: 按照基本回收策略分 引用计数(Reference Counting): 比较古老的回收算法.原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数. ...

  4. JVM调优-Jva中基本垃圾回收算法

    从不同的的角度去划分垃圾回收算法. 按照基本回收策略分 引用计数(Reference Counting) 比较古老的回收算法.原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回 ...

  5. JVM(二) 对象存活判断和垃圾回收算法

    对象的创建 概述 下面简要介绍创建对象的几个重要步骤 : 检查能否在常量池定位到一个类的符号引用,并检查这个符号代表的类是否已被加载,解析和初始化过.如果没有则执行类加载的操作.(即是说对象的引用放在 ...

  6. JVM内存分配策略,及垃圾回收算法

    本人免费整理了Java高级资料,一共30G,需要自己领取;传送门:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q 说起垃圾收集(Garbage Co ...

  7. 小师妹学JVM之:GC的垃圾回收算法

    目录 简介 对象的生命周期 垃圾回收算法 Mark and sweep Concurrent mark sweep (CMS) Serial garbage collection Parallel g ...

  8. JVM学习总结二——垃圾回收算法

    昨天总结了JVM内存分区相关的知识,这次我们将来了解下JVM的另一个核心知识点——垃圾回收算法.这一部分其实并不太难,如果对操作系统的内存处理算法有所了解,那么这部分算法其实只看名字就能明白,两者在原 ...

  9. JVM垃圾回收算法及回收器详解

    引言 本文主要讲述JVM中几种常见的垃圾回收算法和相关的垃圾回收器,以及常见的和GC相关的性能调优参数. GC Roots 我们先来了解一下在Java中是如何判断一个对象的生死的,有些语言比如Pyth ...

随机推荐

  1. 分布式定时任务框架——python定时任务框架APScheduler扩展

    http://bbs.7boo.org/forum.php?mod=viewthread&tid=14546 如果将定时任务部署在一台服务器上,那么这个定时任务就是整个系统的单点,这台服务器出 ...

  2. 快速EDAS字体嵌入问题

    在用edas向国际会议投稿的时候,往往要检查pdf稿件的格式,例如页边距.行距.字体等.经常碰到的一个问题就是字体未嵌入到文件中.因为大家一般用CTex里面的ps2pdf生成pdf文件,图片中的字往往 ...

  3. [爬虫]BeautifulSoup4

    1.Beautiful Soup的简介 Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据.官方解释如下: Beautiful Soup提供一些简单的.python式的函 ...

  4. Clean http handlers in Go

    Introduction For this blog post we are going to take a look at the http.HandlerFunc type and how we ...

  5. loj553 「LibreOJ Round #8」MINIM

    最简单的暴力dp就是f[i][j]表示到i异或和为j的最小花费. 然后我们发现两堆大小为i,j的石子合并,可以更新到一堆大小为k=i,j最高公共的1以下都是1,以上是i|j,权值为v1+v2的石子. ...

  6. mac升级后idea提示Can't start git

    试了官网的解决方案,还是不行,然后到Stack Overflow上面,找到了下面这个方法,完美解决. 在命令行中运行: xcode-select --install 安装软件就可以了.

  7. BZOJ1467_Pku3243 clever Y_EXBSGS

    BZOJ1467_Pku3243 clever Y_EXBSGS Description 小Y发现,数学中有一个很有趣的式子: X^Y mod Z = K 给出X.Y.Z,我们都知道如何很快的计算K. ...

  8. 作为比湖南还火的python网红,零基础要如何系统的开始学习呢?

    Python(发音:英[?pa?θ?n],美[?pa?θɑ:n]),是一种面向对象.直译式电脑编程语言,也是一种功能强大的通用型语言,已经具有近二十年的发展历史,成熟且稳定.它包含了一组完善而且容易理 ...

  9. jenkins+docker 持续构建非docker in docker

    工欲善其事必先利其器,为了解脱程序员的,我们程序员本身发明了很多好用的工具,通过各种工具的组合来达到我们想要的结果 本文采用jenkins docker svn maven作为相关工具,项目sprin ...

  10. CMake入门实战

    本文用来记录基本的Cmake用法,以一个实例,讲解如何通过cmake构建一个一个基本的工程,文件的目录如下: 说明: bin文件夹下的debug和release分别存放编译输出的文件和相关依赖的动态库 ...