纠结的我,给我的JVM系列终于起了第三个名字,害,我真是太难了。从 JVM 到 每日五分钟,玩转 JVM 再到现在的给产品经理讲 JVM ,虽然内容为王,但是标题可以让更多的人看到我的文章,所以,历经了三个选题,最终定下来了这个。

这个名字的由来,且听我给你慢慢道来,从学习知识的角度上来说,最深入的方法就是把知识讲给别人听,那么为什么我要讲给程序员的天敌——产品经理呢?

那么问题的答案很简单,因为我「老婆」就是一个「产品经理」哈哈哈哈哈哈哈(听说现在流行这样玩?

认识的时候她是 Java 开发来着,谁知道领了证就变成了产品。。小 朋 友 你 是 否 有 很 多 ???(手动摊手

废话不多说了,下面开始进入我们的正文~

背景

故事发生在一个明媚的午后,我刚看完《深入理解Java虚拟机》第三章的第三节——垃圾收集算法,我的产品大人开始了例行盘问

产品大大:你天天学的什么啊,我看着好像很眼熟??

我:???你难道忘了你曾经是一个 Java 程序员,JVM 都忘了?

产品大大:JVM 啊,基本上忘的差不多了,要不你给我讲讲,省的我们「开发天天忽悠我」

于是,我就这么做了程序员的叛徒

我:行吧,那我就来给你讲一讲这一节中我的收获吧。

接上集

我:在开始之前,我们先来回顾一下上次讲的东西,上次我们说到了如何判定一个对象是不是垃圾对象(已死),通常来说有两种算法——「引用计数法和可达性分析法」,目前市面上的虚拟机大多数采用的是第二种——可达性分析法。

产品大大:那么这两种方法是不是对应了两个类型的垃圾收集算法呢?

我:真聪明,果然「不是一家人,不进一家门」,这两种分别对应了Reference Counting GC(引用计数垃圾收集)和 Tracing GC(追踪垃圾收集),而我们今天讲的垃圾收集算法都属于追踪垃圾收集的范畴。不过在介绍垃圾收集算法之前,我首先需要向你介绍一个很关键的理论——分代收集理论。

产品大大:好嘞

分代收集理论

我:所谓分代收集理论从某种意义上来说,是一种约定俗称的规范和经验的总结,并不是一个非常严格的规则。

产品大大:嗯嗯,约定大于配置,现在这样的思想在很多地方都有体现,那么到底什么是分代收集呢?

我:且听我慢慢道来,分代收集建立在三个假说之上:

  1. 绝大多数对象都是朝生夕死的。
  2. 熬过越多次的GC的对象越难以消亡。
  3. 跨代饮用相对于同代引用仅占极少一部分。

产品大大:这三个我好像在哪见过,但是记不太清楚了,能不能说的更详细一点

我:由于绝大多数对象都是朝生夕死的,而熬过越多次GC的对象越难消灭掉,这样自然而然的就会把对象分成两个派别,一种是极易发生GC的,一种是极难发生GC的,极易发生GC的生命周期较短,所以也被称之为「新生代」,极难发生GC的对象生命周期较长,所以也可以叫他们「老年代」

产品大大:这么一说,我好像有点明白了,但是为什么要分代呢?

我:如果我们把他们进行分代后,可以对区域进行划分,一部分用于存储新生代,新生代的对象我们只需要去关注那些不被回收的对象就可以,而不用去标注绝大多数需要回收的对象;一部分用于存储老年代,老年代发生GC的频率较低。这两个区域的GC频率是不同的,所以分开进行GC的话可以节省很多时间和存储这些对象的空间。

产品大大:原来是这样,那么为什么会有第三个假说呢?

我:如果出现新生代中存在老年代对象的引用,或者老年代对象中存在新生代对象的引用,这样的现象被我们称之为跨代引用,而我们为了确保可达性分析法的准确性,还需要去遍历老年代中的对象,这样就会造成很大的性能压力和负担。这时第三条结论就应运而生,为什么会有这条结论呢?你想一想,如果一个新生代对象在进行了几次GC后,因为跨代引用的原因,仍然没有被回收掉,那么这个新生代对象就会晋升到老年代中。于是就解决了这个跨代的问题。

产品大大:那么第三个假设对应的措施是什么呢?

我:文字未免太过苍白,这个适合用图来表达,看好咯

我:这样的话,会不会很清晰(得意脸

产品大大:明白了,那我们继续吧,是不是要进入正题了

我:嗯哼,下面我就来介绍最基础的一种算法——标记清除算法

标记-清除

产品大大:这个我知道,就像它名字那样,标记,然后清除,见名知意嘛哈哈哈哈。

我:厉害了,不愧是技术出身的产品,佩服佩服,确实像你所说的那样,就很简单的两步,标记——清除。

我:但是这样的方式由于过于简陋,虽然在对象较少的时候,效率比较快,但是当对象一多起来的话,标记和清除的效率都会有所下降,而且这样的方式会造成一个问题——产生内存碎片,如果剩下的空白格无法放下一个较大的对象时,就会提前触发另外一个GC。

产品大大:说到这里,好像还漏了点东西,GC针对不同的分代是不是有不同的GC叫法来着?

我:对的,我疏忽了,针对新生代的GC一般称之为(Young GC),针对老年代的GC一般称之为(Old GC),如果是堆和方法区全部回收的话,则被称之为Full GC。

产品大大:这样倒也算好记,OK,我们来进入下一个算法吧。

我:下一个算法,可以看作是第一个算法的升级版本,叫做「标记——复制算法」

标记-复制

我:标记复制算法,最开始形态是半区复制,就是把之前的内容按照容量划分成等量的两部分,一部分用完之后,就把剩余存活的对象丢到另一半,然后把这一半进行清除,变成预留的另一块。如果是绝大多数对象需要回收(例如新生代)的情况下,这样的方法就会很便捷高效,但是这是一种牺牲空间来换取时间的做法,我们仅仅有效利用了一半的空间,有一半的空间被浪费掉了。

产品大大:所以后来一定会有所改进的,对吗?(期盼脸

我:没错,新的复制算法不能称之为半区复制了,因为新生代内存范围被分割成了三个部分,一个Eden区和两个Survivor区,他们之间的比例是8:1:1。在进行GC的时候,使用一个Eden和一个Survivor区,然后把剩余的存活对象放到另一个Survior区域中,清理掉剩下的区域,就可以完成一次收集的过程,这样仅仅有百分之十的空间被浪费,相对于优点来说,这样的缺点,我们是完全可以接受的,

产品大大:那如果剩下的Survivor不足以放下剩下存活的对象该怎么办呢?

我:问的好,这个时候就要谈到一个新的概念——「内存担保」了,如果不够,就会去找老年代,如果老年代的「连续空间」大于新生代对象总大小或历次晋升的平均值,就可以借给Survivor区使用,至于为什么是这样,且待我卖个关子(其实是我也不知道哈哈哈哈哈

产品大大:那么这种算法听起来好像没有什么缺点的亚子?

我:并不然,复制的操作会降低回收的效率,而且,如果是老年代进行回收的话,你向谁去借呢?所以又出现了第三种算法——标记整理算法。

标记-整理

产品大大:那么什么是标记整理呢?

我:标记-整理算法是一种移动型的算法,通过将存活对象向一边移动,然后直接清除掉边界外的内存以达到不会产生内存碎片的回收算法。

产品大大:那么这个算法的优点就是在于它不会产生内存碎片,减少了回收的次数,那么它和标记-整理相比孰优孰劣呢?

我:对的,虽然在它移动对象的时候会花费不少的时间和资源,但是相对于标记-清除算法来说,频繁的GC所消耗的时间会更多,当然在实际的使用过程中,这三种算法会在不同的应用场景下结合去使用,比如先使用标记-清除算法,当内存碎片达到一定程度后,再使用标记-整理算法去清除,不同的组合会有不同的效果,具体什么效果,我会在给你介绍一些常见的垃圾收集器时进行讲解(下一节哟

产品大大:好的~ 那今天就先到这里吧,讲的差不多够我吸收个三五天的了,过两天你再给我讲吧~

我:好哒。

最后的最后

咳咳,如果知识无法让你吃饱,那你可以多吃点狗粮哈哈哈哈哈哈(太皮会不会挨打嘻嘻

晒一张产品大大给我的备注。

下面又是「精彩」的恰

「给产品经理讲JVM」:垃圾收集算法的更多相关文章

  1. 💕《给产品经理讲JVM》:垃圾收集器

    前言 在上篇中,我们把 JVM 中的垃圾收集算法有了一个大概的了解,又是一个阴雨连绵的周末,宅在家里的我们又开始了新一轮的学习: 产品大大:上周末我们说了垃圾收集算法,下面是不是要讲一下这些算法的应用 ...

  2. 3星|《给产品经理讲技术》:APP开发技术介绍,没有技术背景的话恐怕只能看懂书中的比喻和结论

    基本是APP开发涉及到的相关技术的入门级介绍.涉及到的知识点与技术细节比较多,不少技术相关的内容并没有像标题暗示的那样没有技术背景也可以看懂,而是涉及到许多专业的术语.原理.也有一些内容是用比喻的方法 ...

  3. JVM笔记-垃圾收集算法与垃圾收集器

    1. 一些概念 1.1 垃圾&垃圾收集 垃圾:在 JVM 语境下,"垃圾"指的是死亡的对象所占据的堆空间. 垃圾收集:所谓"垃圾收集",就是将已分配出去 ...

  4. JVM中垃圾收集算法总结

      通过前面的介绍我们了解了对象创建和销毁的过程.那么JVM中垃圾收集器具体对对象回收采用的是什么算法呢?本文主要记录下JVM中垃圾收集的几种算法. JVM的垃圾回收的算法 标记-清除算法(Mark- ...

  5. 深入浅出JVM之垃圾收集算法

    判断哪些对象需要被回收 引用计数算法: 给对象中添加一个引用计数器,每当有一个地方引用时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象就是不可能再被使用的. 但是JVM没有使 ...

  6. 深入理解JVM(二)--垃圾收集算法

    一. 概述 说起垃圾收集(Garbage Collection, GC), 大部分人都把这项技术当做Java语言的伴随生产物. 事实上, GC的历史远远比Java久远, 1960年 诞生于MIT的Li ...

  7. 给产品经理讲技术,不得不懂的TCP和UDP

    TCP/IP协议,你一定经常听说吧,其中TCP(Transmission Control Protocol)称为传输控制协议,IP(Internet Protocol)称为因特网互联协议,好吧,这都是 ...

  8. 面试刷题25:jvm的垃圾收集算法?

    垃圾收集是java语言的亮点,大大提高了开发人员的效率. 垃圾收集即GC,当内存不足的时候触发,不同的jvm版本算法和机制都有差别. 我是李福春,我在准备面试,今天的问题是: jvm的垃圾回收算法有哪 ...

  9. JVM垃圾收集算法之标记算法

    前言 总所周知,jvm的垃圾收集算法一般包括标记.清除.整理三个阶段,最近在看了有关于垃圾收集的标记算法,记录一下自己的理解. 垃圾收集中标记算法有两种:一种是引用计数法,一种是根搜索算法. 引用记数 ...

随机推荐

  1. 结题报告--洛谷P3915

    题目:点此. 我处理这种多组数据的方法被我叫做“mains法”,就是先假设只有一组数据,写一个代码,然后把那个main函数改成mains,最后写一个真正的main函数. 这个“真正的”main函数一般 ...

  2. iframe 父框架调用子框架的函数

    1.父框架定义: <iframe name="mainframe" id="mainframe" width="100%" scrol ...

  3. 分布式框架Celery(转)

    一.简介 Celery是一个异步任务的调度工具. Celery 是 Distributed Task Queue,分布式任务队列,分布式决定了可以有多个 worker 的存在,队列表示其是异步操作,即 ...

  4. [红日安全]Web安全Day12 – 会话安全实战攻防

    本文由红日安全成员: ruanruan 编写,如有不当,还望斧正. 大家好,我们是红日安全-Web安全攻防小组.此项目是关于Web安全的系列文章分享,还包含一个HTB靶场供大家练习,我们给这个项目起了 ...

  5. php7连接mysql8

    最近因为剁手买了mac所以在mac上搭建lnmp环境. 刚好看到mysql从5.7跳到8,性能据说快上一倍,果断尝鲜! lnmp基本都弄好了,但是到用php连接Mysql这一步出了岔子. 出错原因: ...

  6. 解决不管其他元素z-index设置多高,都在视频下面的方法

    <div style="z-index:-1"> <embed name="Movie1" src="http://ecards.s ...

  7. ReentrantReadWriteLock源码探究

    ReentrantReadWriteLock实现了可重入的读锁和写锁,其中读锁是共享锁,写锁是互斥锁.与ReentrantLock类似,ReentrantReadWriteLock也提供了公平锁和非公 ...

  8. linux环境下安装可操作图库语言Gremlin的图框架HugeGraph

    原创/朱季谦 图数据库是一项比较前沿而逐渐热门的技术,是NoSql数据库的一种,它应用图形理论存储实体之间的关系信息,最主要的组成有两种,结点集和连接结点的边.常见的图数据库有Neo4j,Januas ...

  9. 《Python学习手册 第五版》 -第18章 参数

    在函数的定义和调用中,参数是使用最多喝最频繁的,本章内容就是围绕函数的参数进行讲解 本章重点内容如下: 1.参数的传递 1)不可变得参数传递 2)可变得参数传递 2.参数的匹配模式 1)位置次序:从左 ...

  10. WTM 3.5发布,VUE来了!

    千呼万唤中,WTM的Vue前后端分离版本终于和大家见面了,我曾经跟群里1000多位用户保证过Vue版本会在春天到来,吹过的牛逼总算是圆上了. WTM一如既往地追求最大程度提高生产效率,所以内置的代码生 ...