垃圾回收 - 引用计数法

GC原本是一种“释放怎么都无法被引用的对象的机制”。那么人们自然而然就会想到,可以让所有对象事先记录下“有多少程序引用了自己”。让各对象知道自己的“人气指数”,从而让没有人气的对象自己消失,这就是引用计数法。

1、计数器

计数器表示的是对象的人气指数,也就是有多少程序引用了这个对象。计数器是无符号的整数
在这里插入图片描述
1.1计数器的增减
在GC-标记清除算法的其他算法中,没有分块时mutator会调用下面这样的函数,启动GC分配空闲的内存空间。

garbage_collect(){.....
}

然而在引用计数法中并没有mutator明确启动GC的语句,引用计数法与mutator的执行密切相关,他在mutator的处理过程中通过增减计数器的值来进行内存管理。这涉及到new_obj()函数和update_ptr()函数

1.2 new_obj()函数

new_obj(size){obj = pickup_chunk(size,$free_list)if(obj == NULL) allocation_fail()elseobj.ref_cnt = 1return obj
}

1.3 update_ptr()函数
该函数用于更新指针ptr,使其指向对象obj,同时进行计数器值的增减。

update_ptr(ptr,obj){inc_ref_cnt(obj)dec_ref_cnt(*ptr)*ptr = obj
}inc_ref_cnt(obj){obj.ref_cnt ++;
}dec_ref_cnt(obj){obj.ref_cnt --;if(obj.ref_cnt == 0)for(child : children(obj))dec_ref_cnt(*child)reclaim(obj)
}

该程序具体进行的是以下2项操作:

  • 对指针ptr新引用的对象obj的计数器进行增量操作
  • 对指针ptr之前引用的对象*ptr的计数器进行减量操作

在变更数组元素等的时候会进行指针的更新。通过更新指针,可能会产生没有被任何程序引用的的垃圾对象。引用计数法会监督在更新指针的时候是否有产生垃圾,从而在产生垃圾的时候立即将其回收。

2、优缺点

2.1优点

  • 可即刻回收垃圾
  • 最大暂停时间短
  • 没有必要沿着指针查找。

2.2缺点

  • 计数器值的增减处理繁重
  • 计数器需要占用很多位
  • 实现繁琐复杂
  • 循环引用无法回收

3、延迟引用计数法

因为引用计数法中计数器值的增减处理繁重。于是就产生了延迟引用计数法。计数器增减处理繁重的原因之一是从根的引用变化频繁,因此我们就让从根引用的指针的变换不反映在计数器上。比如我们把重写全局变量指针的update_ptr($ptr,obj)改写成*ptr = obj。
这样一来,即使频繁重写堆中对象的引用关系,对象的计数器值也不会有所变化。但是这样内存管理还是不能顺利进行。因为引用没有反应在计数器上,所以各个对象的计数器没有正确表示出对象本身被引用数。于是就有可能发生对象仍在活动但却被错当成垃圾回收的情况。
在这里插入图片描述
于是,我们在延迟引用计数法中使用ZCT(Zero Count Table),他会事先记录下计数器值在dec_ref_cnt()函数作用下变为0的对象。
在这里插入图片描述
因为计数器值为0的对象不一定都是垃圾,所以暂时先将这些对象保留。

优点:通过延迟减轻了因根引用频繁发生变化导致的计数器增减所带来的额外负担。
缺点:为了延迟计数器的增减,垃圾不能立马回收,导致垃圾压迫成堆,我们也就失去了引用计数法的优点-可即刻回收垃圾。

4、Sticky引用计数法

在引用计数法中,我们有必要研究一件事,那就是要为计数器设置多大的位宽,假设为了反映所有引用,计数器需要一个字(32位机器就是32位)的空间。但是这样回大量消耗内存空间。比如2个字的对象就要附加一个字的计数器,也就是说计数器害的对象所占空间增大了1.5倍
在这里插入图片描述
对此我们有个方法,那就是用来减少计数器位宽的“Sticky引用计数法"。举个例子,我们假设用于计数器的位数为5位,那么这种计数器最多只能数到2的5次方减1,就是31个引用数。如果此对象被大于31个引用对象引用,那么计数器就会溢出。针对计数器溢出,需要暂停堆计数器的管理,对付这种对象,我们主要有两种方法:

4.1、什么都不做
对于计数器溢出的对象,我们可以这样处理:不再增减计数器的值,就把它放着。但是这样一来,即使这个对象成了垃圾(引用次数为0)也不能将其回收,这样就白白浪费了内存空间。

4.2、使用标记清除算法处理
在适当的时候使用标记清除算法来充当引用计数法的后援。这样做的优点是在计数器溢出后即使成了垃圾,程序还是能够回收它,并且还可以回收循环的垃圾。

5、1位引用计数法

1位引用计数法是Stick的一个极端例子,就是计数器的大小只有一位,瞬间就会溢出。

6、部分标记清除法

之前已经讲过,引用计数法存在的一大问题就是不能回收循环的垃圾。这是引用计数法的一大特色,用GC标记清除算法就不会有这种问题。那么我们自然会想到,只要跟之前使用延迟引用计数法时一样,利用GC 标记清除算法不就好了吗?也就是说,可以采用一般情况下执行引用计数法,在某个时刻启动 GC 标记清除算法的方法。

6.1前提
在部分标记清除算法中,对象会被涂成4种颜色来进行管理:

颜色含义表示
绝对不是垃圾的对象(对象产生时的初始颜色)00
绝对是垃圾的颜色01
搜索完毕的对象10
阴影可能是循环垃圾的对象11

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

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

相关文章

使用MATLAB解算炼油厂的选址

背景 记得有一年的数据建模大赛,试题是炼油厂的选址,最后我们采用MATLAB编写(复制)蒙特卡洛算法,还到了省级一等奖,这里把仅有一些记忆和材料,放到这里来,用来纪念消失的青春。 本…

selenium可以编写自动化测试脚本吗?

Selenium可以用于编写自动化测试脚本,它提供了许多工具和API,可以与浏览器交互,模拟用户操作,检查网页的各个方面。下面是一些步骤,可以帮助你编写Selenium自动化测试脚本。 1、安装Selenium库和浏览器驱动程序 首先…

Redis布隆过滤器原理

其实布隆过滤器本质上要解决的问题,就是防止很多没有意义的、恶意的请求穿透Redis(因为Redis中没有数据)直接打入到DB。它是Redis中的一个modules,其实可以理解为一个插件,用来拓展实现额外的功能。 可以简单理解布隆…

Educational Codeforces Round 154 (Rated for Div. 2)

Educational Codeforces Round 154 (Rated for Div. 2) A. Prime Deletion 思路&#xff1a; 因为1到9每个数字都有&#xff0c;所以随便判断也质素即可 代码 #include<bits/stdc.h> using namespace std; #define int long long #define rep(i,a,n) for(int ia;i<…

数学建模-点评笔记 9月3日

1.摘要&#xff1a;关键方法和结论&#xff08;精炼的语言&#xff09;要说明&#xff0c;方法的合理性和意义也可以说明。 评委先通过摘要筛选&#xff08;第一轮&#xff09; 2.时间序列找异常值除了3西格玛还有针对时间序列更合适寻找的方法 3.模型的优缺点要写的详细一点…

vue3 页面显示中文,分页显示中文

vue3 分页默认为英文 &#xff0c;但想要中文显示 那么在App.vue中的代码为三步即可&#xff0c;引入中文&#xff0c;声明中文 &#xff0c;绑定中文&#xff1b; 1. import zhCn from element-plus/es/locale/lang/zh-cn&#xff1b; 2. let locale zhCn; 3. :locale&q…

Snipaste_2023-08-22_16-09-41.jpg

原因 cd 目录名 (想要补全的时候出现以下错误) cd /o-bash: cannot create temp file for here-document: No space left on device解决方案 可以使用df -h命令查看磁盘空间的使用情况,删除一些不必要的文件或调整其他文件的存储位置来释放空间,或者还可以考虑扩大磁盘容量 df …

数据结构1 -- leetcode练习

三. 练习 3.1 时间复杂度 用函数 f ( n ) f(n) f(n) 表示算法效率与数据规模的关系&#xff0c;假设每次解决问题需要 1 微秒&#xff08; 1 0 − 6 10^{-6} 10−6 秒&#xff09;&#xff0c;进行估算&#xff1a; 如果 f ( n ) n 2 f(n) n^2 f(n)n2 那么 1 秒能解决多…

PHP NBA球迷俱乐部系统Dreamweaver开发mysql数据库web结构php编程计算机网页

一、源码特点 PHP NBA球迷俱乐部系统是一套完善的web设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 基于PHP的NBA球迷俱乐部 二、功能介绍 1、前台主要功能&#xff1a; 系统首页 网站介…

2023_Spark_实验一:Windows中基础环境安装

Ⅰ、WINDOWS中安装JDK1.8 一、下载安装包 链接&#xff1a;百度网盘 请输入提取码 所在文件夹&#xff1a;根目录或者大数据必备工具--》开发工具(前端后端)--》后端 下载文件名称&#xff1a;jdk-8u191-windows-x64.exe 二、安装JDK 1.现在转到下载的exe文件可用的文件夹&…

从传统到智能化:汽车内部通信的安全挑战与SecOC解决方案

01/需求背景 Demand background 在传统的汽车电子结构中&#xff0c;车内的电控单元&#xff08;ECU&#xff09;数量和复杂性受到限制&#xff0c;通信带宽也受到限制。因此&#xff0c;人们普遍认为车内各个ECU之间的通信是可靠的。只要ECU节点接收到相应的消息&#xff0c…

实际并行workers数量不等于postgresql.conf中设置的max_parallel_workers_per_gather数量

1 前言 本文件的源码来自PostgreSQL 14.5&#xff0c;其它版本略有不同并行workers并不能显箸提升性能。个人不建议使用并行worker进程&#xff0c;大多数情况下采用postgresql.conf默认配置即可。 PostgreSQL的并行workers是由compute_parallel_worker函数决定的&#xff0c…

【人工智能】—_线性分类器、感知机、损失函数的选取、最小二乘法分类、模型复杂性和过度拟合、规范化

文章目录 Linear predictions 线性预测分类线性分类器感知机感知机学习策略损失函数的选取距离的计算 最小二乘法分类求解最小二乘分类矩阵解法一般线性分类模型复杂性和过度拟合训练误差测试误差泛化误差复杂度与过拟合规范化 Linear predictions 线性预测 分类 从具有有限离…

MySQL-数据类型

MySQL-数据类型 数值类型bittinyintfloatdecimal 字符串和文本类型charvarcharblobtext 日期和时间类型enum-枚举类型set-集合类型 数值类型 数据类型说明bit(M)位类型。M指定位数&#xff0c;默认值为1&#xff0c;范围1-64.tinyint [unsigned]带符号范围:-128 - 127&#xf…

JavaScript 生成 16: 9 宽高比

这篇文章只是对 for 循环一个简单应用&#xff0c;没有什么知识含量。 可以跳过这篇文章。 只是我用来保存一下我的代码&#xff0c;保存在本地我嫌碍眼&#xff0c;总想把他删了。 正文部分 公式&#xff1a;其中 width 表示宽度&#xff0c;height 表示高度 16 9 w i d t…

【微服务部署】一、使用docker-compose部署Jenkins、SonarQube、PostgreSQL

一、安装 1、编写docker-compose部署Postgres、SonarQube、Jenkins的yml文件jenkins-compose.yml Postgres&#xff1a;作为SonarQube的数据库存储SonarQube&#xff1a;代码质量检查Jenkins&#xff1a;jenkins/jenkins:lts镜像&#xff0c;jenkinsci/blueocean镜像缺少node…

22.3D等距社交媒体菜单的悬停特效

效果 源码 <!doctype html> <html><head><meta charset="utf-8"><title>CSS Isometric Social Media Menu</title><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.…

Vue框架--理解MVVM

我们知道&#xff0c;MVVM是Model-View-ViewModel的简写。它本质上就是MVC的改进版。我们看看MVVM的模型架构&#xff0c;如下所示: 架构理解与实例

git大文件推送报错

报错信息 不多掰扯&#xff0c;直接上报错信息和截图 Delta compression using up to 8 threadsRPC failde; HTTP 413 curl 22 The requested URL returned error: 413 Request Entity Too Large从以上的报错信息不难看出推送仓库的时候&#xff0c;请求体过大&#xff0c;为…

供热管网安全运行监测,提升供热管网安全性能

城市管网是城市的“生命线”之一&#xff0c;是城市赖以生存和发展的基础&#xff0c;在城市基础设施高质量发展中发挥着重要作用。供热管网作为城市生命线中连接供热管线与热用户的桥梁&#xff0c;担负着向企业和居民用户直接供热的重要职责。随着城市热力需求的急剧增加&…