分代收集 + 垃圾回收算法

分代假说

1. 弱分代假说(Weak Generational Hypothesis):绝大多数对象都是朝生夕灭的

2. 强分代假说(Strong Generational Hypothesis):熬过越多次垃圾收集过程的对象就越难以消亡

3. 跨代引用假说(Intergenerational Reference Hypothesis):跨代引用相对于同代引用来说仅占极少数

💛 收集器应该将Java堆划分出不同的区域,然后将回收对象依据其年龄(年龄即对象熬过垃圾收集过程的次数)分配到不同的区域之中存储。

显而易见,如果一个区域中大多数对象都是朝生夕灭,难以熬过垃圾收集过程的话,那么把它们集中放在一起,每次回收时只关注如何保留少量存活而不是去标记那些大量将要被回收的对象(解释1),就能以较低代价回收到大量的空间;如果剩下的都是难以消亡的对象,那把它们集中放在一块,虚拟机便可以使用较低的频率来回收这个区域,这就同时兼顾了垃圾收集的时间开销和内存的空间有效利用(解释2)。

 解释1:

 解释2:

        时间开销 ——> 支取扫描1%,比扫描99%快得多;
        内存空间有效利用 ——> 1%移动时不会直接移动,而是复制一份,将复制移动过去,成功后,删除原有的。


新生代 —— 存放朝生夕死的对象

老年代 —— 存放新生代回收后还存活的对象,不容易死的对象

💛 在新生代中,每次垃圾收集时都发现有大批对象死去,而每次回收后存活的少量对象,将会逐步晋升(解释3)到老年代中存放。

 解释3:

 当年龄达到13时,就进入老年代


跨代引用

分代收集有一个问题:跨代引用

比如说新生代中有一个对象A引用老年代的一个对象 B,只要老年代的对象不回收,新生代的这个对象也不会被回收。每次新生代回收时还是要去扫(判断A是否需要回收,此时也需要去判断A引用的B是否被回收),也不能直接将A放入老年代,因为可能在A的年龄为12时,对象B就被回收了。

解决跨代引用的问题

💛 存在互相引用关系的两个对象,是应该倾向于同时生存或者同时消亡的。

举个例子,如果某个新生代对象存在跨代引用,由于老年代对象难以消亡,该引用会使得新生代对象在收集时同样得以存活,进而在年龄增长之后晋升到老年代中,这时跨代引用也随即被消除了。

跨代引用只占极少数,就不应再为了少量的跨代引用去扫描整个老年代,也不必浪费空间专门记录每一个对象是否存在及存在哪些跨代引用,只需在新生代上建立一个全局的数据结构(该结构被称为“记忆集”,Remembered Set)。这个结构把老年代划分成若干小块,标识出老年代的哪一块内存会存在跨代引用。
一旦出现跨代引用,就会出现在老年代的跨代引用区域。当发生新生代收集时,只有包含了跨代引用的小块内存里的对象会进行扫描。

虽然这种方法需要在对象改变引用关系(如将自己或者某个属性赋值)时维护记录数据的正确性,会增加一些运行时的开销,但比起收集时扫描整个老年代来说仍然是划算的。

垃圾回收算法

一、标记-清除算法

标记:哪些对象可以存活或者哪些对象可以回收

它的主要缺点有两个:

  • 第一个是执行效率不稳定。
    如果Java堆中包含大量对象,而且其中大部分是需要被回收的,这时必须进行大量标记和清除的动作,导致标记和清除两个过程的执行效率都随对象数量增长而降低;

  • 第二个是内存空间的碎片化问题。
    标记、清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致当以后在程序运行过程中需要分配较大对象时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。

基本不使用

二、标记-复制算法

根据IBM研究,新生代中的对象有98%熬不过第一轮收集(普通场景下,无法保证每次都是这样),因此不需要按照1:1的比例来划分新生代的内存空间,而是使用了8:1:1分配内存空间。

 每次进行收集时,将前8:1空间的存活对象一次性复制到另外的1比例,然后清理掉前8:1空间的朝生夕死的对象。

💛 内存的分配担保好比我们去银行借款,如果我们信誉很好,在98%的情况下都能按时偿还,于是银行可能会默认我们下一次也能按时按量地偿还贷款,只需要有一个担保人能保证如果我不能还款时,可以从他的账户扣钱,那银行就认为没有什么风险了。

标记-复制算法虽然弥补了标记-清除算法的缺点,但标记-复制算法还是有自己的缺点:

首先就是在对象存活率较高时要进行较多的复制操作,效率将会降低

还有一种情况,就是在十分之九的的对象里超过十分之一存活,那么复制到右边区域时空间大小就不够了。

为了解决这些,出现了标记-整理算法。

三、标记-整理算法

标记过程仍与标记-清除算法相同,但后续让所有存活的对象都向内存空间一端移动,然后直接清理掉边界以外的内存。

弊端

  • 像在老年代这种每次回收都有大量对象存活区域,移动存活对象并更新所有引用这些对象的地方将会是一种极为负重的操作,而且这种对象移动操作必须全程暂停用户应用程序(解释4)才能进行 ——> 宕机 stop the world 

但不移动的话,碎片化问题严重,得不到解决也会导致性能、存储量降低。

解释4:

如果不暂停的话,刚标记的时候只占据一块,标记完以后整理时可能就变成了占据了两块。

💛 通常标记-清除算法也是需要停顿用户线程来标记、清理可回收对象的,只是停顿时间相对而言要来的短而已。

于是混合式出现了,让虚拟机平时多数时间都采用标记-清除算法,暂时容忍内存碎片的存在,直到内存空间的碎片化程度已经大到影响对象分配时,再采用标记-整理算法收集一次,以获得规整的内存空间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/82391.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java开发面试题 | 2023

Java基础 接口和抽象类的区别?Java动态代理HashMap 底层实现及put元素的具体过程currenthashmap底层实现原理?map可以放null值吗,currenthashmap为什么不能放null值synchronze和reetrantlock区别?怎样停止一个运行中的线程&#…

提高批量爬虫工作效率

大家好!作为一名专业的爬虫程序员,我今天要和大家分享一些关于提高批量爬虫工作效率的实用技巧。无论你是要批量采集图片、文本还是视频数据,这些经验都能帮助你在大规模数据采集中事半功倍。废话不多说,让我们开始吧!…

MATLAB | 七夕节用MATLAB画个玫瑰花束叭

Hey又是一年七夕节要到了,每年一次直男审美MATLAB绘图大赛开始hiahiahia,真的这些代码越写越不知道咋写,又不想每年把之前的代码翻出来再发一遍,于是今年又对我之前写的老代码进行了点优化组合,整了个花球变花束&#…

Transformer是什么,Transformer应用

目录 Transformer应用 Transformer是什么 Transformer应用:循环神经网络 语言翻译:注重语句前后顺序 RNN看中单个特征; CNN:看中特征之间时序性 模型关注不同位置的能力 Transformer是什么 Transformer是一个利用注意力机制来提高模型…

如何在pycharm中指定GPU

如何在pycharm中指定GPU 作者:安静到无声 个人主页 目录 如何在pycharm中指定GPU打开编辑配置点击环境变量添加GPU配置信息推荐专栏在Pycharm运行程序的时候,有时候需要指定GPU,我们可以采用以下方式进行设置: 打开编辑配置 点击环境变量 添加GPU配置信息 添加名称:CU…

新的 Python URL 解析漏洞可能导致命令执行攻击

Python URL 解析函数中的一个高严重性安全漏洞已被披露,该漏洞可绕过 blocklist 实现的域或协议过滤方法,导致任意文件读取和命令执行。 CERT 协调中心(CERT/CC)在周五的一份公告中说:当整个 URL 都以空白字符开头时&…

华为网络篇 RIP路由标记-31

难度2复杂度2 目录 一、实验原理 二、实验拓扑 三、实验步骤 四、实验过程 总结 一、实验原理 路由标记tag是用于进行路由过滤的,它给相关的路由打标记,然后应用于路由策略中,路由器会根据策略进行路由过滤。比如,给静态路由…

【开源项目】Stream-Query的入门使用和原理分析

前言 无意间发现了一个有趣的项目,Stream-Query。了解了一下其基本的功能,可以帮助开发者省去Mapper的编写。在开发中,我们会编写entity和mapper来完成业务代码,但是Stream-Query可以省去mapper,只写entity。 快速入…

在线HmacSHA256加密工具--在线获取哈希值又称摘要

具体请前往: 在线计算HmacSha256工具

剑指offer全集系列(1)

目录 JZ3 数组中重复的数字 JZ4 二维数组中的查找 JZ5 替换空格 JZ6 从尾到头打印链表 JZ18 删除链表的节点 JZ22 链表中倒数最后k个结点 题目为剑指offer top100题目, 欢迎大家来学习😘 JZ3 数组中重复的数字 数组中重复的数字_牛客题霸_牛客网在一个长度为…

【Linux】传输层协议:UDP和TCP

争做西格玛男人 文章目录 一、UDP协议1.端口号2.理解UDP报头3.UDP的特点(面向数据报,全双工) 二、TCP协议1.理解TCP报头某些TCP的策略1.1 TCP报头字段(TCP的黏包问题)1.2 网络协议栈和linux系统的联系(以p…

配置使用Gitee账号认证登录Grafana

三方社会化身份源 集成gitee第三方登录 第三方登录的原理 所谓第三方登录,实质就是 OAuth 授权。用户想要登录 A 网站,A 网站让用户提供第三方网站的数据,证明自己的身份。获取第三方网站的身份数据,就需要 OAuth 授权。 举例来…

verilog学习笔记6——锁存器和触发器

文章目录 前言一、锁存器1、基本SR锁存器——或非门实现2、基本SR锁存器——与非门实现3、门控SR锁存器4、门控D锁存器 二、触发器1、 电平触发的RS触发器/同步SR触发器2、电平触发的D触发器/D型锁存器3、边沿触发的D触发器4、脉冲触发的RS触发器 三、边沿触发、脉冲触发、电平…

攻防世界-fileinclude

原题 解题思路 题目已经告诉了,flag在flag.php中,先查看网页源代码(快捷键CTRLU)。 通过抓包修改,可以把lan变量赋值flag。在cookie处修改。新打开的网页没有cookie,直接添加“Cookie: languagephp://filte…

PCAP01介绍和STM32模拟SPI驱动

一.芯片介绍 Pcap01是德国acam公司设计的一款革命性的电容测量芯片。该芯片 内部有DSP计算单元,可以直接将电容元件接到Pcap01芯片,然后芯片计算出容值大小,通过SPI总线将电容容值数据传送给CPU,电容测量完全数字化。 二,测量原…

excel常见的数学函数篇2

一、数学函数 1、ABS(number):返回数字的绝对值 语法:ABS(数字);返回数字的绝对值;若引用单元格,把数字换为单元格地址即可 2、INT(number):向小取整 语法:INT(数字);若引用单元格…

QT SSL handshake failed问题分析与解决 QT基础入门【网络编程】openssl

问题: 使用https方式进行post 和get请求时,有时候会出现SSL handshake failed的问题,其实是调用Qt QNetworkAccessManager出现的问题。 其实SSL握手是建立HTTPS连接过程的第一步。为了验证和建立连接,用户的浏览器和网站的服务器必须经过一系列检查(握手),从而建立HTTP…

【STM32RT-Thread零基础入门】 4. 线程介绍(理论)

文章目录 前言一、线程的概念二、线程的调度三、上下文切换四、线程的重要属性1. 线程栈2. 线程的状态3. 线程优先级4. 线程时间片5. 线程的入口函数 五、RT-Thread命令查看系统线程信息总结 前言 前文中的最后一个任务发现,一个main()函数很难同时实现按键功能和闪…

postgresql的在windows下的安装

postgresql的在windows下的安装 下载安装步骤超级用户设置密码本地化设置安装信息安装完成 查看postgresql服务pgAdmin的使用打开命令 行工具查询数据库版本 创建数据库 下载 官网地址 https://www.postgresql.org/ 下载页面 https://www.postgresql.org/download/ windows下…