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. 报错:com.mysql.jdbc.MysqlDataTruncation: Data truncation xxxx

    报错 Out of range value for column 'pk' at row 1:表的字段长度不够 Data too long for column 'ip' at row 1:表的字段长 ...

  2. Go语言核心36讲29

    在上篇文章中,我们主要说的是互斥锁,今天我和你来聊一聊条件变量(conditional variable). 前导内容:条件变量与互斥锁 我们常常会把条件变量这个同步工具拿来与互斥锁一起讨论.实际上, ...

  3. SPFA和链式前向星

    链式前向星 一种存储图的数据结构 建立一个结构体和一个数组加一个变量,这里的to代表边\((u,v)\)中的\(v\)结点,而\(edge\)数组的索引\(idx\)代表\(u\),其中\(w\)代表 ...

  4. tomcat 随windows启动

    有时候服务器会突然断电,维护管理员只会帮我们启动服务器,但是不会不会帮我们启动Tomcat. 1.进入tomcat的bin文件夹,找到startup.bat,右键生成快捷方式到桌面. 2.点击桌面左下 ...

  5. JDK中内嵌JS引擎介绍及使用

    原文: JDK中内嵌JS引擎介绍及使用 - Stars-One的杂货小窝 最近研究阅读这个APP,其主要功能就是通过一个个书源,从而实现移动端阅读的体验 比如说某些在线小说阅读网站,会加上相应的广告, ...

  6. Hexo+next主题美化

    前言 需要在Hexo下配置next主题 Hexo配置next主题教程:https://www.cnblogs.com/xuande/p/16641543.html 更改配置以后使用素质三连:hexo ...

  7. ExcelToObject.NPOI 两行代码导出Excel报表、读取Excel数据

    简介 作为一个dotnet开发者,经常面对业务系统中大量报表导入导出,经常写了一堆的重复代码.最近发现一个操作excel的神器:ExcelToObject.NPOI,两行代码就能导出一个报表,两行代码 ...

  8. vue 原生js-实现下拉框

    <template> <div class="por"> <div class="selectBox" style="w ...

  9. python网络爬虫数据解析之正则

    本节内容,讲解爬取网络图片,利用正则匹配图片地址 请求网页之后,响应部分内容如下图: 1 时间:2023/1/7 10:42 2 功能描述 3 1.进行指定标签的定位 4 2.标签或者标签对应的属性中 ...

  10. 腾讯出品小程序自动化测试框架【Minium】系列(一)环境搭建之第一个测试程序

    一.什么是Minium? minium是为小程序专门开发的自动化框架,使用minium可以进行小程序UI自动化测试. 当然,它的能力不仅仅局限于UI自动化, 比如: 使用minium来进行函数的moc ...