1.分代收集理论

  1.1分代收集理论假说

  1.2分代收集理论奠定的垃圾收集器原则

  1.3基于分代收集理论的内存划分-跨代引用假说

2.垃圾回收

3.垃圾收集算法

  3.1标记-清除算法

  3.2标记-复制算法

  3.3标记-整理算法

  

1、分代收集理论

  当前商用虚拟机的垃圾收集器,大多采用的是分代收集理论的设计原则。它实际上是一套符合大多数程序实际运行情况的经验算法。

1.1分代收集理论假说

  它建立在以下假说上

  1)弱分代假说:大多数对象都是朝生夕死

  2)强分代假说:熬过越多次垃圾收集的对象越难以死亡

  

1.2分代收集理论奠定的垃圾收集器原则

  1)收集器应该将内存区域划分为不同的区域

  2)将对象按照年龄(熬过垃圾回收的次数)分到不同的区域中去

  一个区域中大多数对象都是朝生夕死,那么就可以只关注存活的对象,而不用去标记大量要被回收的对象,提高效率

  一个区域中都是熬过多次垃圾回收的对象,那么就可以使用较低的频率去回收这个区域

1.3基于分代收集理论的内存划分-跨代引用假说

  设计者一般会至少把内存区域划分为新生代和老年代两个区域。但是分代收集也不仅仅是划分区域这么简单。对象不是孤立的,他们之间会相互引用,不同区域的也有相互引用。如果我们想要对新生代进行垃圾回收,我们不得不去老年代去看是否有新生代的引用。所以就有了跨代引用假说:跨代引用相对于同代引用来说只占极少数。

  根据这个假说我们不应该为了少量的跨代引用去扫描整个老年代。只需要在新生代上建立一个全局的数据结构-记忆体

  这个结构把老年代划分为若干个小块,标识出哪一块内容存在跨代引用。这样子只需要扫描存在跨代引用的区域即可。

  这样子做的缺点就是在对象的引用关系发生变化时,需要去维护这个数据结构。

2.垃圾回收

  基于分代收集理论和内存划分,产生了多种的垃圾收集模式

1)部分收集

  新生代收集(Minor GC/YoungGC):目标只是新生代

  老年代收集(Major GC/Old GC):目标只是老年代

  混合收集(Mixed GC):整个新生代和部分老年代。目前只有G1收集器有这种模式

3)整堆收集:收集整个JAVA堆和方法区

3.垃圾收集算法

垃圾收集算法可分为两类:引用计数式垃圾收集和追踪式垃圾收集。JAVA虚拟机只涉及第二种。下面也只讲第二种。

3.1标记-清除算法

  该算法分为两个部分,标记与清除。标记需要回收的对象,回收,或者标记不需要回收的对象,回收未标记的对象。
  

优点:显然可见,该方法十分之简单,而且很高效,很快,因为对比其他方法,都是要标记的,而在清除阶段,也不需要执行什么抹掉内容的操作,只用把要“清除”的内存空间设为可用即可,可以说毫不费力,所以很快。
    缺点:缺点也很明显,看上面我们经过标记-清除算法的堆内存空间,可用的区域根本就不连续,存在大量的内存碎片,如果需要分配一个大空间的内存而找不到不够大小的连续内存,就会导致又一次的垃圾回收

3.2标记-复制算法

3.2.1简介

  这个算法实际是对上面的标记-清除算法的一种改进。解决内存不连续的问题。
  将内存区域分成大小相同的两块,每次只使用其中一个区域,当进行垃圾回收时,将存活的对象复制到另一个区域上(连续存放),然后把已经使用过的区域一次性全部清除。

优点:解决了标记-清除算法内存不连续的问题,可以看到,这里内存是十分连续的,然后,其速度也还是可以的,虽然比不上标记-清除,但还是比标记-整理快很多很多
    缺点:可用内存只有一半,十分浪费内存空间。

  现在商用虚拟机大多采用这种算法去回收新生代

3.2.2Apple式回收

  Andrew Apple对该算法作出了优化,形成了Apple式回收。

  因为研究显示,新生代中有98%的对象熬不过第一次收集。基于这个现象,Apple式回收的具体做法是,把内存区域分为一块大的Eden和两块小的Survivor。Eden和其中一块Survivor正常使用,另外一块作为用来复制存活对象的区域。它们的大小是8:1:1.Eden为8,两个Survivor分别为一。这样子有效的使用的内存空间就达到了90%。但是这样子也存在问题,如果存活的对象过多,超过了Survivor的大小,就存在问题。所以,还有一个充当备用的内存(大多数在老年代)。

  HotSpot的Serial、ParNew等新生代收集器都是采用这种方式

3.3标记-整理算法

  标记复制算法适用于对象朝生夕死的新生代,却不适用于老年代。因为它的对象大多一致存活下去。针对老年代就有了标记-整理算法

  标记-整理算法不是直接对可回收对象进行清除,而是让所有存活对象都向内存空间一端移动,然后清除边界以外的内存。

  进行标记整理时,jvm会将灰色的都往前移,让黑色的都在灰色后面,然后以最后一个灰色的为边界,将边界外的内存空间清除掉。
  可以看到,经过标记-整理算法的堆内存变的整整齐齐,干干净净,也就是内存连续了,
       优点:保证了堆内存的连续,不会浪费堆内存
       缺点:首先,要在内存中移动对象,这很慢很低效,并且,在移动时,需要全程暂停应用程序。

  和标记清除算法相比,它多了个移动对象内存的步骤。两者都存在弊端,前者不考虑移动对象内存,那么内存碎片化就需要依赖更为复杂的内存分配器和内存访问其来解决。而移动对象内存又需要暂停程序。从整个程序的吞吐量来说,还是移动内存效率更高。

  程序的吞吐量是赋值器()和收集器效率的总和。不移动对象会使收集器的效率提升,但是内存分配和访问效率降低了。HotSpot虚拟机里面关注吞吐量的Oarallel Old收集器是基于标记整理算法的,而关注延迟的CMS收集器则是基于标记清除算法的。

  还可以两者混合使用,平时使用标记清除算法,当内存碎片化影响到大内存的分配时,采用标记整理算法。CMS就是采用的这种方法
  

JAVA虚拟机07-垃圾回收-分代收集理论和垃圾收集算法的更多相关文章

  1. Java虚拟机之垃圾回收详解一

    Java虚拟机之垃圾回收详解一 Java技术和JVM(Java虚拟机) 一.Java技术概述: Java是一门编程语言,是一种计算平台,是SUN公司于1995年首次发布.它是Java程序的技术基础,这 ...

  2. 深入理解java虚拟机(二)-----垃圾回收

    做一个java程序员很是幸福,不用管不用的对象如何被回收,但是我认为了解一下也不是坏事. 一.如何判断对象已经死亡? 在进行垃圾回收之前,第一件事肯定是判断对象是否已经死亡.1.引用计数算法给对象添加 ...

  3. 每日一问:讲讲 Java 虚拟机的垃圾回收

    昨天我们用比较精简的文字讲了 Java 虚拟机结构,没看过的可以直接从这里查看: 每日一问:你了解 Java 虚拟机结构么? 今天我们必须来看看 Java 虚拟机的垃圾回收算法是怎样的.不过在开始之前 ...

  4. 深入理解Java虚拟机(三)——垃圾回收策略

    所谓垃圾收集器的作用就是回收内存空间中不需要了的内容,需要解决的问题是回收哪些数据,什么时候回收,怎么回收. Java虚拟机的内存分为五个部分:程序计数器.虚拟机栈.本地方法栈.堆和方法区. 其中程序 ...

  5. 【java虚拟机】垃圾回收机制详解

    作者:平凡希 原文地址:https://www.cnblogs.com/xiaoxi/p/6486852.html 一.为什么需要垃圾回收 如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分 ...

  6. java虚拟机之垃圾回收算法

    标记-清除算法: 这是最基础的,就是之前所讲的两次标记,首先标记出所有 需要回收的对象,然后进行统一清除, 这有两缺点:一是效率低,标记和清除(开启低优先级进行回收)都是低效率的.第二是空间问题,标记 ...

  7. 深入理解java虚拟机【垃圾回收算法】

    Java虚拟机的内存区域中,程序计数器.虚拟机栈和本地方法栈三个区域是线程私有的,随线程生而生,随线程灭而灭:栈中的栈帧随着方法的进入和退出而进行入栈和出栈操作,每个栈帧中分配多少内存基本上是在类结构 ...

  8. Java虚拟机:JVM内存分代策略

    版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! Java虚拟机根据对象存活的周期不同,把堆内存划分为几块,一般分为新生代.老年代和永久代(对HotSpot虚拟机而言),这就是JVM的内存 ...

  9. java虚拟机 之 垃圾回收机制

    一.如何判断对象已死 垃圾回收器并不是java独有的,垃圾回收器的作用就是回收对象释放内存空间,那么如何判断哪些对象应该被回收呢? 在Java语言中是采用GC Roots来解决这个问题.如果一个对象和 ...

  10. Java 虚拟机的垃圾回收

    背景 垃圾收集(Garbage Collection,GC),GC的历史比Java久远,1960年诞生于MIT的Lisp是第一门真正使用内存动态分配和垃圾收集技术的语言. 对于Java来说,运行时区域 ...

随机推荐

  1. 编码工具使用(go语言)

    1.课程介绍 Git基础课程和实操 Goland介绍以及常用快捷键使用 Go delve 调试 你想要的linux 这里都有 2.版本控制工具介绍 原始的版本控制 修改文件,保存文件副本 版本控制的起 ...

  2. VH6501模板工程介绍(一)

    VH6501硬件结构 1.式样 1.正向有5个灯,用来指示干扰的触发状态,干扰类型(数字或模拟),通道通信以及设备状态. 2.两个DB9接口(公头male和母头female),这是CAN或CANFD通 ...

  3. qtcreator配置cmake+mingw开发环境

    环境准备 cmake 添加到PATH环境变量. mingw: 这里我用的mingw是Qt自带的,我将其添加到PATH环境变量中. 在cmd中执行 mingw32-make.exe 和 cmake查看命 ...

  4. Pod控制器详解

    Pod控制器详解 7.1 Pod控制器介绍 Pod是kubernetes的最小管理单元,在kubernetes中,按照pod的创建方式可以将其分为两类: 自主式pod:kubernetes直接创建出来 ...

  5. 第二十六节:urllib、requests、selenium请求库代理设置

    1.urllib代理设置 1 from urllib.error import URLError 2 from urllib.request import ProxyHandler 3 from ur ...

  6. 2A锂电池充电管理IC,具有恒压/恒流充电模式

    PW4052 是一颗适用于单节锂电池的.具有恒压/恒流充电模式的充电管理 IC.该芯片采用开关型的工作模 式, 能够为单节锂电池提供快速. 高效且简单的充电管理解决方案. PW4052 采用三段式充电 ...

  7. hook详解和应用

    一.hook的作用区域 1.客户端的过程 链接服务器 拿回资源 渲染(解析资源)资源 初始化(自执行) 页面逻辑 等待用户输入 加密数据 提交数据 2.hook的本质 在这些流程任意环节中插入自己的代 ...

  8. Elasticsearch模糊查询、多字段in查询、时间范围查询,DSL和java API两种方式

    Elasticsearch模糊查询.多字段in查询.时间范围查询,DSL和java API两种方式 项目场景: Elasticsearch模糊查询某字段.多字段in查询.时间范围查询,通过DSL和ja ...

  9. axios 中get 和post传参

    axios中get和ppost传参的方式: params是添加到url的请求字符串中的,一般用于get请求. data是添加到请求体(body)中的, 一般用于post请求. 上面,只是一般情况. 其 ...

  10. C++可执行文件绝对路径获取与屏蔽VS安全检查

    :前言 前几天写新项目需要用到程序所在绝对路径的时候,发现网上居然一点相关分享都没有. :_pgmptr 翻箱倒柜找出了几本教程,发现了一个叫_pgmptr的东西. 进去看了一下,在stdlib.h里 ...