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. Ueditor、FCKeditor、Kindeditor编辑器漏洞

    Ueditor.FCKeditor.Kindeditor编辑器漏洞 免责声明: Ueditor编辑器漏洞 文件上传漏洞 XSS漏洞 SSRF漏洞 FCKeditor编辑器漏洞 查看FCKeditor版 ...

  2. 数据结构初阶--顺序表(讲解+C++类模板实现)

    顺序的概念与结构 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储.在数组上完成数据的增删查改. 一般分为两种:静态顺序表和动态顺序表 静态顺序表 #define ...

  3. ArcObjects SDK开发 010 FeatureLayer

    1.FeatureLayer的结构 FeatureLayer是我们开发的时候用的最多的API之一,其实现的接口以及关联的其他API也非常多.下面我们就用一张图来整体看下FeatureLayer有哪些常 ...

  4. 【SQL基础】多表查询:子查询、连接查询(JOIN)、组合查询(UNION集合运算)

    〇.概述 1.内容 JOIN表连接(内连接INNER JOIN/JOIN)(外连接LEFT/RIGHT (OUTER) JOIN) 集合运算-UNION联合 2.建表语句 drop table if ...

  5. 【Java EE】Day06 JDBC连接池介绍、C3P0连接池实现、Druid连接池实现、JDBCTemplate

    一.数据库连接池介绍 1.引入 之前:每次都要获取连接释放连接 现在:连接重复使用 2.概念: 存放数据库连接的容器 3.实现 DataSource接口 三种实现 标准实现 连接池实现 C3P0 Dr ...

  6. 网络编程 - OSI七层协议详解

    目录 网络编程基础 软件开发架构 网络编程简介 OSI七层协议简介 OSI协议之物理连接层 OSI协议之数据链路层 网络相关专业名词 OSI之网络层 OSI协议之传输层 传输层之TCP协议/UDP协议 ...

  7. Linux—软件管理

    Linux 软件管理 1.软件管理简介 Redhat和Centos中软件管理是依靠软件包管理器(RPM)来实现的. RPM(Redhat Package Manager)软件包管理器提供了在linux ...

  8. 12、HSSFWorkbook实现多张sheet导出

    转载自 一.封装一个通用的装载数据的实体类: import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsCon ...

  9. cmd窗口中java命令报错。错误:找不到或无法加载主类 java的jdk安装过程中踩过的坑

    错误: 找不到或无法加载主类 HelloWorld 遇到这个问题时,我尝试过网上其他人的做法.有试过添加classpath,也有试过删除classpath.但是依然报错,这里javac可以编译通过,说 ...

  10. 学习.NET MAUI Blazor(四)、路由

    Web应用程序的可以通过URL将多个页面串联起来,并且可以互相跳转.Web应用主要是使用a标签或者是服务端redirect来跳转.而现在流行的单页应用程序 (SPA) ,则通过路由(Router)来实 ...