引言

之前我们学习了 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. json数据取值

    var data = JSON.parse(JSON.stringify(position, null, 4));

  2. SVN客户端和服务器端下载地址

    https://sourceforge.net/projects/tortoisesvn/files/1.9.7/Application/TortoiseSVN-1.9.7.27907-x64-svn ...

  3. LeetCode Javascript实现 258. Add Digits 104. Maximum Depth of Binary Tree 226. Invert Binary Tree

    258. Add Digits Digit root 数根问题 /** * @param {number} num * @return {number} */ var addDigits = func ...

  4. 你不知道的JavaScript--Item8 函数,方法,构造函数调用

    1.函数调用 Function绝对是JavaScript中的重中之重.在JavaScript中,Function承担了procedures, methods, constructors甚至是class ...

  5. CentOS6.*安装gitolite

    http://www.kankanews.com/ICkengine/archives/64748.shtml 2人收藏此文章, 发表于4小时前(2013-10-22 16:12) , 已有26次阅读 ...

  6. Nginx 入门学习教程

    昨天听一个前同事说他们公司老大让他去研究下关于Nginx 方面的知识,我想了下Nginx 在如今的开发技术栈中应该会很大可能会用到,所以写篇博文记录总结下官网学习教程吧. 1. 什么是Nginx? 我 ...

  7. Java 学习笔记 (四) Java 语句优化

    这个问题是从headfirst java看到的. 需求: 一个移动电话用的java通讯簿管理系统,要求最有效率的内存使用方法. 下面两段程序的优缺点,哪个占用内存更少. 第一段: Contact[]c ...

  8. IDEA使用教程

    以下内容引自: https://www.cnblogs.com/yjd_hycf_space/p/7483921.html IntelliJ IDEA使用教程(很全) 这个编辑器我就不再多做介绍了.直 ...

  9. get.go

    //获取空间文件 ))     resp, err := http.DefaultClient.Do(req)     if err != nil {         return nil, err ...

  10. 【Floyd】BZOJ1491: [NOI2007]社交网络

    Description   Solution n<=100自然联想Floyd 设两个数组d[n][n]存最短距离,t[n][n]存最短路径条数 更新d的时候顺便更新t,乘法原理 if(d[i][ ...