JAVA虚拟机07-垃圾回收-分代收集理论和垃圾收集算法
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-垃圾回收-分代收集理论和垃圾收集算法的更多相关文章
- Java虚拟机之垃圾回收详解一
Java虚拟机之垃圾回收详解一 Java技术和JVM(Java虚拟机) 一.Java技术概述: Java是一门编程语言,是一种计算平台,是SUN公司于1995年首次发布.它是Java程序的技术基础,这 ...
- 深入理解java虚拟机(二)-----垃圾回收
做一个java程序员很是幸福,不用管不用的对象如何被回收,但是我认为了解一下也不是坏事. 一.如何判断对象已经死亡? 在进行垃圾回收之前,第一件事肯定是判断对象是否已经死亡.1.引用计数算法给对象添加 ...
- 每日一问:讲讲 Java 虚拟机的垃圾回收
昨天我们用比较精简的文字讲了 Java 虚拟机结构,没看过的可以直接从这里查看: 每日一问:你了解 Java 虚拟机结构么? 今天我们必须来看看 Java 虚拟机的垃圾回收算法是怎样的.不过在开始之前 ...
- 深入理解Java虚拟机(三)——垃圾回收策略
所谓垃圾收集器的作用就是回收内存空间中不需要了的内容,需要解决的问题是回收哪些数据,什么时候回收,怎么回收. Java虚拟机的内存分为五个部分:程序计数器.虚拟机栈.本地方法栈.堆和方法区. 其中程序 ...
- 【java虚拟机】垃圾回收机制详解
作者:平凡希 原文地址:https://www.cnblogs.com/xiaoxi/p/6486852.html 一.为什么需要垃圾回收 如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分 ...
- java虚拟机之垃圾回收算法
标记-清除算法: 这是最基础的,就是之前所讲的两次标记,首先标记出所有 需要回收的对象,然后进行统一清除, 这有两缺点:一是效率低,标记和清除(开启低优先级进行回收)都是低效率的.第二是空间问题,标记 ...
- 深入理解java虚拟机【垃圾回收算法】
Java虚拟机的内存区域中,程序计数器.虚拟机栈和本地方法栈三个区域是线程私有的,随线程生而生,随线程灭而灭:栈中的栈帧随着方法的进入和退出而进行入栈和出栈操作,每个栈帧中分配多少内存基本上是在类结构 ...
- Java虚拟机:JVM内存分代策略
版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! Java虚拟机根据对象存活的周期不同,把堆内存划分为几块,一般分为新生代.老年代和永久代(对HotSpot虚拟机而言),这就是JVM的内存 ...
- java虚拟机 之 垃圾回收机制
一.如何判断对象已死 垃圾回收器并不是java独有的,垃圾回收器的作用就是回收对象释放内存空间,那么如何判断哪些对象应该被回收呢? 在Java语言中是采用GC Roots来解决这个问题.如果一个对象和 ...
- Java 虚拟机的垃圾回收
背景 垃圾收集(Garbage Collection,GC),GC的历史比Java久远,1960年诞生于MIT的Lisp是第一门真正使用内存动态分配和垃圾收集技术的语言. 对于Java来说,运行时区域 ...
随机推荐
- Java反应式编程(1)
您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来- 前面把Java函数式编程的由来和最主要的核心知识点讲完了.包括比较难懂的Lambda表达式是怎么演变而来的也全部都撸了一遍.Lambda表达式这 ...
- [leetcode] 713. Subarray Product Less Than K
题目 Given an array of integers nums and an integer k, return the number of contiguous subarrays where ...
- 使用vite + vue3 + ant-design-vue + vue-router + vuex 创建一个管理应用
使用vite + vue3 + ant-design-vue + vue-router + vuex 创建一个管理应用的记录 使用vite 创建项目 我创建的node 版本是 v16.17.1 使用N ...
- 【ASP.NET Core】MVC控制器的各种自定义:修改参数的名称
在上一篇中,老周演示了通过实现约定接口的方式自定义控制器的名称. 至于说自定义操作方法的名称,就很简单了,因为有内置的特性类可以用.看看下面的例子. [Route("[controller] ...
- EluxJS-让你像切蛋糕一样拆解前端巨石应用
大家好,EluxJS是一套基于"微模块"和"模型驱动"的跨平台.跨框架『同构方案』,欢迎了解... 可怕的巨石怪 工作中最可怕的是什么?是遇到业务复杂且乱作一团 ...
- 记一次windows10电脑连上wifi无法上网的解决问题
前言 今天下午同学的电脑能连上wifi,但是却上不了互联网 开始思考 首先想到的肯定是WiFi驱动问题,但是wifi能连上大部分的原因可能就不是驱动问题了,为了彻底排除这个因素,我用到了我的usb网卡 ...
- angr_ctf——从0学习angr(二):状态操作和约束求解
状态操作 angr中提到的状态(state)实际上是一个Simstate类,该类可由Project预设得到.预设完成后,还可以根据需要对某些部分进行细化操作. 一个state包含了程序运行到某个阶段时 ...
- Selenium4+Python3系列(十二) - 测试框架的设计与开发
前言 自己从未没想过能使用python来做自动化测试框架的设计.开发. 可能有人会好奇说,六哥,你怎么也用python写测试框架了? 领导说: python你也没有实际工作经验,可能就是自己自学的. ...
- 粘包、struct模块、进程并行与并发
目录 粘包现象 struct模块 粘包代码实战 udp协议(了解) 并发编程理论 多道技术 进程理论 进程并行与并发 进程的三状态 粘包现象 1.服务端连续执行三次recv 2.客户端连续执行三次se ...
- VMware虚拟机开机黑屏解决方法
挂起时可以看到显示,但是开机就黑屏 解决方法: 命令提示符,鼠标右键点击"命令提示符",弹出菜单之后选择"以管理员身份运行" 在命令提示符窗口中输入" ...