垃圾回收 - 分代垃圾回收

分代垃圾回收在对象中导入了“年龄”的概念,通过优先回收容易成为垃圾的对象,提高垃圾回收的效率。

1、新生代对象和老年代对象

分代垃圾回收中把对象分类成几代,针对不同的代使用不同的 GC 算法,我们把刚生成的对象称为新生代对象,到达一定年龄的对象则称为老年代对象。
众所周知,新生代对象大部分会变成垃圾。如果我们只对这些新生代对象执行 CC会怎么样呢?除了引用计数法以外的基本算法,都会进行只寻找活动对象的操作(如标记清除算法的标记阶段和 复制算法等)。因此,如果很多对象都会死去,花费在 GC上的时间应该就能减少。
我们将对新对象执行的 CC 称为新生代 GC (minor GC)。mainor 在这里的意思是“小规模的”。新生代 GC 的前提是大部分新生代对象都没存活下来,GC 在短时间内就结束了。
另一方面,新生代 GC 将存活了一定次数的新生代对象当作老年代对象来处理。我们把类似于这样的新生代对象上升为老年代对象的情况称为晋升 (promotion).。
因为老年代对象很难成为垃圾,所以我们对老年代对象减少执行 GC 的频率。相对于新生代GC,我们将面向老年代对象的 GC 称为老年代 GC (major CC)。
在这里有一点需要注意,那就是分代垃圾回收不能单独用来执行 GC。我们需要把它和之前介绍的基本算法结合在一起使用,来提高那些基本算法的效率。
也就是说,分代垃圾回收不是跟GC 标记一清除算法和 GC 复制算法并列在一起供我们选择的算法,而是需要跟这些基本算法一并使用。

2、Unger的分代垃圾回收

在Ungar 的分代垃圾回收中,堆的结构如下图所示。我们总共需要利用 4个空间,分别是生成空间、2个大小相等的率存空间以及老年代空间,并分别用 new_start、survivor1_start、survivor2_start、old_start 这4 个变量引用它们的开头。我们将生成空间和幸存空间合称为新生代空间。新生代对象会被分配到新生代空间,老年代对象则会被分配到老年代空间里。Ungar 在论文里把生成空间、幸存空间以及老年代空间的大小分别设成了 140K字节、28K 字节和 940K宇节。
此外我们准备出一个和堆不同的数组,称为记录集(remembered set),设为rs。

在这里插入图片描述

生成空间就如它的字面意思一样,是生成对象的空间,也就是进行分配的空间。当生成空间满了的时候,新生代 GC 就会启动,将生成空间中的所有活动对象复制,这跟GC 复制算法是一个道理。目标空间是幸存空间。
2个幸存空间和CC复制算法里的 From 空间、To 空间很像,我们经常只利用其中的一个。在每次执行新生代 GC 的时候,活动对象就会被复制到另一个幸存空间里。在此我们将正在使用的幸存空间作为 From 幸存空间,将没有使用的幸存空间作为To幸存空间。
不过新生代GC 也必须复制生成空间里的对象。也就是说,生成空间和 From 幸存空间这两个空间里的活动对象都会被复制到To幸存空间里去。这就是新生代 CC。
只有从一定次数的新生代 CC 中存活下来的对象才会得到晋升,也就是会被复制到老年代空间去。
在这里插入图片描述

分代垃圾回收的优点是只将垃圾回收的重点放在新生代对象身上,以此来缩减GC所需要的时间。不过考虑到从老年代对象的引用,结果还是要搜索堆中的所有对象,这样一来就大大削减了分代垃圾回收的优势。所以就利用到了——记录集。
记录集用来记录从老年代到新生代对象的引用。这样新生代GC就可以不搜索老年代空间的所有对象,只通过搜索记录集来发现从老年代到新生代对象的引用。

3、记录集

记录集被用于高效地寻找从老年代对象到新生代对象的引用。具体来说,在新生代GC时将记录集看成根,并进行搜索,以发现指向新生代空间的指针。
在这里插入图片描述

记录集基本上是用固定大小的数组来实现的。各个元素是指向对象的指针。
那么,我们该怎么往记录集里记录对象呢?这就是下一节要介绍的“写入屏障”了。

4、写入屏障

在分代垃圾回收中,为了将老年代对象记录到记录集里,我们利用写入屏障 (write barrier)。在mutator 更新对象间的指针的操作中,写入屏障是不可或缺的。write_barrier()函数的伪代码如下所示。这个函数跟引用计数法中出现的 update_ptr()函数是在完全相同的情况下被调用的。

write_barrier (obj, field, new_obj){if (obj >= $old_start && new_obj < $old_start && obj.remembered == false)$rs [$rs-indez] = obj$rs_index++obj.remembered = true*field = new_obj
}

参数obj是发出引用的对象,obj 内存在要更新的指针,而 field指的就是 obj 内的域。new_obj 是在指针更新后成为引用目标的对象。
if判断主要是检查以下三点:

  • 发出引用的对象是不是老年代对象
  • 指针更新后的引用的目标对象是不是新生代对象
  • 发出引用的对象是否还没有被记录到记录集中

当这些检查结果都为真时,obj 就被记录到记录集中了。

5、对象的结构

在Ungar 的分代垃圾回收中,对象的头部中除了包含对象的头部中类和大小之外,还有以下这3条信息:

  • 对象的年龄(age)
  • 已经复制完成的标志(forwarded)
  • 已经向记录集记录完毕的标志(remembered)

age表示的是对象从新生代 CC 中存活下来的次数,这个值如果超过一定次数(AGE_MAX),对象就会被当成老年代对象处理。我们在 CC 复制算法和 GC标记压缩算法中也用到过 forwarded, 这里它的作用是一样的,都是用来防止重复复制相同对象的标志。这里的remembered也一样,是用来防止向记录集中重复记录的标志。不过 remembered只用于老年代对象,age 和forwarded只用于新生代对象。
此外,跟GC复制算法一样,在这里我们也使用forwarding指针。在torvrarting 指针中利用obj.field1,用obj.forwarding 访问 obj.field1.
Ungar 的分代垃圾回收中用到的对象的结构如下图所示
在这里插入图片描述

6、分配

分配是在生成空间进行的。执行分配的new_obj()函数如下所示

new_obj (size){if ($new_free + size ›= $survivor1_start)minor_gc ()if ($new_free + size ›= $survivor1_start)allocation_fail ()}obj = $new_free$new_free += sizeobj.age = 0obj.forwarded = falseobj.remembered = falseobi.size = sizereturn obj
}

7、优缺点

优点:吞吐量得到改善
缺点:在部分程序中会起到反作用。“很多对象年纪经轻就会死”这个法则毕竟只适合大多数情况,并不适用于所有程程序。当然、对象会活得很久的程序也有很多。对这样的程序执行分代垃圾回收,就会产生以下两个问题

  • 新生代GC所花费的时间增多
  • 老年代GC频繁运行
    而且,写入屏障导致的额外负担降低了吞吐量。只有当新生代GC 带来的速度提升效果大于写入屏障对速度造成的影响时,分代垃级回收才能够更好地发挥作用。当这个大小关系不成立时,分代址圾回收就没有什么作用,或者说反而可能会起到反作用。这种情况下我们还是使用基本算法更好。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

三维数字沙盘电子沙盘虚拟现实模拟推演大数据人工智能开发教程第15课

三维数字沙盘电子沙盘虚拟现实模拟推演大数据人工智能开发教程第15课 现在不管什么GIS平台首先要解决的就是数据来源问题&#xff0c;因为没有数据的GIS就是一个空壳&#xff0c;下面我就目前一些主流的数据获取 方式了解做如下之我见&#xff08;主要针对互联网上的一些卫星…

java+ssm+mysql电梯管理系统

项目介绍&#xff1a; 使用javassmmysql开发的电梯管理系统&#xff0c;系统包含管理员&#xff0c;监管员、安全员、维保员角色&#xff0c;功能如下&#xff1a; 管理员&#xff1a;系统用户管理&#xff08;监管员、安全员、维保员&#xff09;&#xff1b;系统公告&#…

Android签名查看

查看签名文件信息 第一种方法&#xff1a; 1.打开cmd&#xff0c;执行keytool -list -v -keystore xxx.keystore&#xff0c;效果如下图&#xff1a; 第二种方法: 1.打开cmd&#xff0c;执行 keytool -list -v -keystore xxxx.keystore -storepass 签名文件密码&#xff0…

Python调试学习资料

Python调试学习资料 python -m pdb example.py网络资源 Python代码调试的几种方法总结Python 程序如何高效地调试&#xff1f;Python Debugging With Pdbpdb — The Python DebuggerThe Python Debugger (pdb)Python Debugger with ExamplesHow to port Python 2 Code to Pyth…

功率信号源可以应用在哪些方面

功率信号源是一种能够产生一定功率的信号源&#xff0c;广泛应用于各个领域。下面将介绍功率信号源在电子、通信、工业和科研等方面的应用。 在电子行业中&#xff0c;功率信号源是一种重要的测试工具。它可以产生各种波形的信号&#xff0c;如正弦波、方波、脉冲波等&#xff…

[Java]异常

目录 1.异常的概念与体系结构 1.1异常的概念 1.1.1算术异常 1.1.2数组越界异常 1.1.3空指针异常 1.2异常的体系结构 1.3异常的分类 2.异常的处理 2.1 防御式编程 2.2异常的抛出 2.3异常的捕获 2.3.1 异常声明throws 将光标放在抛出异常方法上&#xff0c;alt Insert …

合宙Air724UG LuatOS-Air LVGL API控件--下拉框 (Dropdown)

下拉框 (Dropdown) 在显示选项过多时&#xff0c;可以通过下拉框收起多余选项。只为用户展示列表中的一项。 示例代码 -- 回调函数 event_handler function(obj, event)if (event lvgl.EVENT_VALUE_CHANGED) thenprint("Option:", lvgl.dropdown_get_symbol(obj)…

IMX6ULL移植篇-uboot源码主要文件说明

一. uboot 源码分析前提 由于 uboot 会使用到一些经过编译才会生成的文件&#xff0c;因此&#xff0c;我们在分析 uboot的时候&#xff0c;需要先编译一下 uboot 源码工程。 这里所用的开发板是 nand-flash 版本。 本文学习续上一篇文章&#xff0c;如下&#xff1a; IMX6U…

Task :app:compileDebugKotlin FAILED

gradle.properties 里面加上 android.enableJetifiertrue

【LeetCode】19. 删除链表的倒数第 N 个结点

19. 删除链表的倒数第 N 个结点&#xff08;中等&#xff09; 方法&#xff1a;快慢指针 思路 为了找到倒数第 n 个节点&#xff0c;我们应该先找到最后一个节点&#xff0c;然后从它开始往前数 n-1 个节点就是要删除的节点。 对于一般情况&#xff1a;设置 fast 和 slow 两个…

idea配置gitLab

前言&#xff1a;网上有很多类似的文章&#xff0c;但描述不够详细 步骤1&#xff1a;安装git 如果安装成功再次点击TEST按钮展示如下&#xff1a;git版本 步骤2&#xff1a;idea配置gitlab 查看当前项目管理的 远程仓库再git的地址&#xff0c;该地址可是gitLab的&#xff0…

DNS解析

1.DNS介绍 DNS 表示域名系统。此系统实质上是用于整理和识别各个域名的网络电话簿。电话簿将“Acme Pizza”之类的名称转换为要拨打的正确电话号码&#xff0c;而 DNS 将“www.google.com”之类的网络地址转换为托管该网站的计算机的物理 IP 地址&#xff0c;如“74.125.19.147…

OpenCV(二十七):图像距离变换

1.像素间距离 2.距离变换函数distanceTransform() void cv::distanceTransform ( InputArray src, OutputArray dst, int distanceType, int maskSize, int dstType CV_32F ) src:输入图像&#xff0c;数据类型为CV8U的单通道图像dst:输出图像&#xff0c;与输入图像…

RabbitMQ学习笔记

1、什么是MQ&#xff1f; MQ全称message queue&#xff08;消息队列&#xff09;&#xff0c;本质是一个队列&#xff0c;FIFO先进先出&#xff0c;是消息传送过程中保存消息的容器&#xff0c;多 用于分布式系统之间进行通信。 在互联网架构中&#xff0c;MQ是一种非常常见的…

js中call、apply和bind:

文章目录 一、区别:二、案例&#xff1a;三、实现&#xff1a;【1】call实现【2】apply实现【3】bind实现 一、区别: call、apply、bind相同点&#xff1a;都是改变this的指向&#xff0c;传入的第一个参数都是绑定this的指向&#xff0c;在非严格模式中&#xff0c;如果第一个…

大数据时代下的精准营销

在大数据时代&#xff0c;人们的信息越来越透明&#xff0c;留在网络上的各种数据也是企业进行营销的一个重要的生产要素。一直以来&#xff0c;营销的科学性正是因为运用了自然科学中一级互联网中的数据收集手段&#xff0c;严谨的记录、搜集和分析消费者的各项数据和日常生活…

STS4 New 安装Spring Bean Configuration File

背景介绍 在创建spring项目后&#xff0c;如果想想创建spring bean Configuration的时候&#xff0c;发下菜单没有这个选项&#xff0c;需要通过下载Spring Roo插件可满足该操作。 参考案例 参考地址&#xff1a; STS4 New 菜单没有Spring Bean Configuration File选项_SQZHA…

企业网络小实验-MUX-Vlan(NAT)

路漫漫其修远兮&#xff0c;吾将上下而求索 直接上实验 实验说明 模拟公司的部门实验&#xff0c; &#xff08;1&#xff09;公司主机如图所示&#xff0c;配置DNS服务器&#xff0c;配置NAT地址转换&#xff08;使用easy-ip的形式&#xff09;访问外网。 &#xff08;2&…

【性能测试】Jenkins+Ant+Jmeter自动化框架的搭建思路

前言 前面讲了Jmeter在性能测试中的应用及扩展。随着测试的深入&#xff0c;我们发现在性能测试中也会遇到不少的重复工作。 比如某新兴业务处于上升阶段&#xff0c;需要在每个版本中&#xff0c;对某些新增接口进行性能测试&#xff0c;有时还需要在一天中的不同时段分别进行…

Lumion 和 Enscape 应该选择怎样的笔记本电脑?

Lumion 和 Enscape实时渲染对配置要求高&#xff0c;本地配置不够&#xff0c;如何快速解决&#xff1a; 本地普通电脑可一键申请高性能工作站&#xff0c;资产安全保障&#xff0c;供软件中心&#xff0c;各种软件插件一键获取&#xff0c;且即开即用&#xff0c;使用灵活&am…