【C 数据结构-动态内存管理】4. 无用单元收集(垃圾回收机制)

文章目录

  • 【 1. 问题描述与解决方法 】
  • 【 2. 中断回收机制 】

【 1. 问题描述与解决方法 】

  • 问题描述
    动态存储管理的运行机制可以概括为:当用户发出申请空间的请求后,系统向用户分配内存;用户运行结束释放存储空间后,系统回收内存。这两部操作都是在用户给出明确的指令后,系统对存储空间进行有效地分配和回收。但是在实际使用过程中,有时会因为用户申请了空间,但是 内存在使用完成后没有向系统发出释放的指令,导致存储空间既没有被使用也没有被回收,变为了无用单元或者会产生悬挂访问的问题
    • 无用单元 是一块用户不再使用,但是系统无法回收的存储空间。
      例如,在C语言中,用户可以通过 malloc 和 free 两个功能函数来动态申请和释放存储空间,当用户使用 malloc 申请的空间使用完成后,没有使用 free 函数进行释放,那么该空间就会成为无用单元。

    • 悬挂访问 :假设使用 malloc 申请了一块存储空间,有 多个指针同时指向这块空间,当其中一个指针完成使命后,私自将该存储空间使用 free 释放掉,导致 其他指针处于悬空状态,如果 释放掉的空间被再分配后,再通过之前的指针访问,就会造成错误,数据结构中称这种访问为悬挂访问。

  • 解决方法
    解决存储空间可能成为无用单元或者产生悬挂访问的方法有两个:
    1. 每个申请的存储空间设置一个计数域,这个计数域 记录的是 指向该存储空间的指针数目,只有当计数域的值为 0 时,该存储空间才会被释放
    2. 中断回收机制,即在程序运行时, 所有的存储空间无论是处于使用还是空闲的状态,一律不回收,当系统中的 可利用空间表为空时,将程序 中断,对当前 不再使用状态的存储空间一律回收,全部链接成一个新的可利用空间表后,程序继续执行。下面将详细介绍第二种方法。
  • PS:实际上,无用单元收集本身都是很 费时间 的,所以 无用单元的收集不适用于实时处理的情况中使用

【 2. 中断回收机制 】

  • 如果想使用上面的第二种解决方法,可以分为两步进行:
    1. 对所有当前正在使用的 存储空间加上被占用的标记(对于广义表来说,可以在每个结点结构的基础上,添加一个 mark 的标志域。)在初始状态下,所有的存储空间全部标志为 0表示未被占用,被占用时程序标记为 1
    2. 依次遍历所有的存储空间,将所有标记为 0 的存储空间链接成一个新的可利用空间表。
  • 对正在被占用的存储空间进行标记的方法有以下三种:
    • 从当前正在工作的指针变量开始,采用 递归 算法依次将所有表中的存储结点中的标志域全部设置为 1;
    • 第一种方法中使用递归算法实现的遍历。而递归底层使用的栈的存储结构,所以也可以直接使用 的方式进行遍历;
    • 以上两种方法都是使用栈结构来记录遍历时指针所走的路径,便于在后期可以沿原路返回。所以第三种方式就是使用 其他的方法代替栈的作用
  • 对被占用的存储空间进行标记的第三种实现方法:
    添加三个指针,p 指针指向当前遍历的结点,t 指针永远指向 p 的父结点,q 指向 p 结点的表头或者表尾结点。在遍历过程遵循以下原则:
    • 当 q 指针指向 p 的表头结点时,可能出现 3 种情况:
      • p 结点的表头结点只是一个元素结点,没有表头或者表尾,这时只需要对该表头结点打上标记后令 q 指向 p 的表尾;
      • p 结点的表头结点是空表或者是已经做过标记的子表,这时直接令 q 指针指向 p 结点的表尾即可;
      • p 结点的表头是未添加标记的子表,这时就需要遍历子表,令 p 指向 q,q 指向 q 的表头结点。同时 t 指针相应地往下移动,但是在移动之前需要记录 t 指针的移动轨迹。记录的方法就是令 p 结点的 hp 域指向 t,同时设置 tag 值为 0。
    • 当 q 指针指向 p 的表尾结点时,可能出现 2 种情况:
      • p 指针的表尾是未加标记的子表,就需要遍历该子表,和之前的类似,令 p 指针和 t 指针做相应的移动,在移动之前记录 t 指针的移动路径,方法是:用 p 结点的 tp 域指向 t 结点,然后在 t 指向 p,p 指向 q。
      • p 指针的表尾如果是空表或者已经做过标记的结点,这时 p 结点和 t 结点都回退到上一个位置。
        由于 t 结点的回退路径分别记录在结点的 hp 域或者 tp 域中,在回退时需要根据 tag 的值来判断:如果 tag 值为 0 ,t 结点通过指向自身 hp 域的结点进行回退;反之,t 结点通过指向其 tp 域的结点进行回退。
  • 例如,下图为一个待遍历的广义表:
    在这里插入图片描述
  • 该广义表每个结点的结构如下图所示:
    在这里插入图片描述
  • 在遍历广义表时,从广义表的 a 结点开始,则 p 指针指向结点 a,同时 a 结点中 mark 域设置为 1,表示已经遍历过,t 指针为 nil,q 指针指向 a 结点的表头结点,初始状态如下图所示:
    在这里插入图片描述
  • 由于 q 指针指向的结点 b 的 tag 值为 1,表示该结点为表结构,所以此时 p 指向 q,q 指向结点 c,同时 t 指针下移,在 t 指针指向结点 a 之前,a 结点中的 hp 域指向 t,同时 a 结点中 tag 值设为 0。效果如下图所示:
    在这里插入图片描述
  • 通过 q 指针指向的结点 c 的 tag=1,判断该结点为表结点,同样 p 指针指向 c,q 指针指向 d,同时 t 指针继续下移,在 t 指针指向 结点 b 之前,b 结点的 tag 值更改为 0,同时 hp 域指向结点 a,效果图如下图所示:
    在这里插入图片描述
  • 通过 q 指针指向的结点 d 的 tag=0,所以,该结点为原子结点,此时根据遵循的原则,只需要将 q 指针指向的结点 d 的 mark 域标记为 1,然后让 q 指针直接指向 p 指针指向结点的表尾结点,效果图如下图所示:
    在这里插入图片描述
  • 当 q 指针指向 p 指针的表尾结点时,同时 q 指针为空,这种情况的下一步操作为 p 指针和 t 指针全部上移动,即 p 指针指向结点 b,同时 t 指针根据 b 结点的 hp 域回退到结点 a。同时由于结点 b 的tag 值为 0,证明之前遍历的是表头,所以还需要遍历 b 结点的表尾结点,同时将结点 b 的 tag 值改为 1。效果图如下图所示:
    在这里插入图片描述
  • 由于 q 指针指向的 e 结点为表结点,根据 q 指针指向的 e 结点是 p 指针指向的 b 结点的表尾结点,所以所做的操作为:p 指针和 t 指针在下移之前,令 p 指针指向的结点 b 的 tp 域指向结点 a,然后给 t 赋值 p,p 赋值 q。q 指向 q 的表头结点 f。效果如下图所示:
    在这里插入图片描述
  • 由于 q 指针指向的结点 f 为原子结点,所以直接 q 指针的 mark 域设为 1 后,直接令 q 指针指向 p 指针指向的 e 结点的表尾结点。效果如下图所示:
    在这里插入图片描述
  • 由于 p 指针指向的 e 结点的表尾结点为空,所以 p 指针和 t 指针都回退。由于 p 指针指向的结点 b 的 tag 值为 1,表明表尾已经遍历完成,所以 t 指针和 p 指针继续上移,最终遍历完成。

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习之基于Tensorflow卷积神经网络智能体操健身系统

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 随着人们健康意识的提高和数字化技术的快速发展,智能健身系统逐渐成为健身领域的新趋势。…

MT8370_联发科MTK8370(Genio 510)芯片性能规格参数

MT8370芯片是一款利用超高效的6nm制程工艺打造的边缘AI平台,具有强大的性能和功能。这款芯片集成了六核CPU(2x2.2 GHz Arm Cortex-A78 & 4x2.0 GHz Arm Cortex-A55)、Arm Mali-G57 MC2 GPU、集成的APU(AI处理器)和DSP,以及一个HEVC编码加速引擎&…

C语言 动态内存管理

目录 1. C/C程序的内存分配2. 动态内存分配的作用3. malloc - 分配内存4. free - 释放内存5. calloc - 分配并清零内存6. realloc - 调整之前分配的内存块7. 常见的动态内存的错误7.1 对空指针解引用7.2 对动态开辟空间的越界访问7.3 对非动态开辟内存使用free7.4 使用free释放…

代码随想录算法训练营第十九天:二叉树go

代码随想录算法训练营第十九天:二叉树go 226.翻转二叉树 力扣题目链接(opens new window) 翻转一棵二叉树。 ​​ 这道题目背后有一个让程序员心酸的故事,听说 Homebrew的作者Max Howell,就是因为没在白板上写出翻转二叉树,最…

jmeter分布式集群压测

目的:通过多台机器同时运行 性能压测 脚本,模拟更好的并发压力 简单点:就是一个人(控制机)做一个项目的时候,压力有点大,会导致结果不理想,这时候找几个人(执行机&#x…

Parts2Whole革新:多参照图定制人像,创新自定义肖像生成框架!

DeepVisionary 每日深度学习前沿科技推送&顶会论文分享,与你一起了解前沿深度学习信息! Parts2Whole革新:多参照图定制人像,创新自定义肖像生成框架! 引言:探索多条件人像生成的新篇章 在数字内容创作…

Autosar PNC网络管理配置-UserData的使用

文章目录 前言ComComSignalComIPdu CanNmSignal Mapping总结 前言 之前配置的网络管理报文中的data都由ComM管理,后面客户新增了需求,最后两个byte需要发送Wakeup Reason,本文记录一下相关配置的修改 Com ComSignal 之前配置的PN_TX&…

应用层协议——HTTP协议

1. 认识HTTP协议 HTTP(Hyper Text Transfer Protocol)协议又叫做超文本传输协议,是一个简单的请求-响应协议,HTTP通常运行在TCP之上。 超文本的意思就是超越普通的文本,http允许传送文字,图片&#xff0c…

XAMPP是什么?XAMPP好不好用?

XAMPP是一个免费且开源的软件套件,用于在个人计算机上轻松搭建和运行 Apache 服务器、MySQL 数据库、PHP 和 Perl,让用户可以在个人电脑上搭建服务器环境的平台。 XAMPP的由来是 X(表示跨平台)、Apache、MySQL、PHP 和 Perl 的首字母缩写。 它集成了这…

Autosar NvM配置-手动配置Nvblock及使用-基于ETAS软件

文章目录 前言NvDataInterfaceNvBlockNvM配置SWC配置RTE Mapping使用生成的接口操作NVM总结前言 NVM作为存储协议栈中最顶层的模块,是必须要掌握的。目前项目基本使用MCU带的Dflash模块,使用Fee模拟eeprom。在项目前期阶段,应该充分讨论需要存储的内容,包括应用数据,诊断…

《Fundamentals of Power Electronics》——隔离型CUK转换器、

以下是隔离型CUK转换器的相关知识点: Cuk电路的隔离型版本获得方式不同。基础非隔离型Cuk电路如下图所示。 将上图中电容C1分成两个串联的电容C1a和C1b,得到结果如下图所示。 在两个电容之间插入一个变压器,得到如下图所示电路。 变压器极性…

再议大模型微调之Zero策略

1. 引言 尽管关于使用Deepspeed的Zero策略的博客已经满天飞了,特别是有许多经典的结论都已经阐述了,今天仍然被问到说,如果我只有4块40G的A100,能否进行全量的7B的大模型微调呢? 正所谓“纸上得来终觉浅,…

C#知识|将选中的账号信息展示到控制台(小示例)

哈喽,你好啊,我是雷工! 上篇学习了控件事件的统一关联, 本篇通过实例练习继续学习事件统一处理中Tag数据获取、对象的封装及泛型集合List的综合运用。 01 实现功能 在上篇的基础上实现,点击选中喜欢的账号&#xff0…

Day1| Java基础 | 1 面向对象特性

Day1 | Java基础 | 1 面向对象特性 基础补充版Java中的开闭原则面向对象继承实现继承this和super关键字修饰符Object类和转型子父类初始化顺序 多态一个简单应用在构造方法中调用多态方法多态与向下转型 问题回答版面向对象面向对象的三大特性是什么?多态特性你是怎…

Transformer详解:从放弃到入门(三)

上篇文章中我们了解了多头注意力和位置编码,本文我们继续了解Transformer中剩下的其他组件。 层归一化 层归一化想要解决一个问题,这个问题在Batch Normalization的论文中有详细的描述,即深层网络中内部结点在训练过程中分布的变化问题。  …

秘籍解锁 primegaming亚马逊免费游戏领取+下载安装教程秘籍解锁

秘籍解锁!primegaming亚马逊免费游戏领取下载安装教程秘籍解锁! 亚马逊作为几大游戏平台之一也是常常送出各种免费以供玩家们游玩,就在近日,亚马逊平台优势豪掷千金为玩家们送出了两款大作,分别是古墓丽影年度版与乐高…

《设计一款蓝牙热敏打印机》

主控芯片用易兆威蓝牙ic,通讯接口:蓝牙、串口、usb 安卓apk用java kotlin编写、上位机用Qt编写。

PX4二次开发快速入门(三):自定义串口驱动

文章目录 前言 前言 软件:PX4 1.14.0稳定版 硬件:纳雷NRA12,pixhawk4 仿照原生固件tfmini的驱动进行编写 源码地址: https://gitee.com/Mbot_admin/px4-1.14.0-csdn 修改 src/drivers/distance_sensor/CMakeLists.txt 添加 add…

uniapp 监听APP切换前台、后台插件 Ba-Lifecycle

监听APP切换前台、后台 Ba-Lifecycle 简介(下载地址) Ba-Lifecycle 是一款uniapp监听APP切换前台、后台的插件,简单易用。 截图展示 也可关注博客,实时更新最新插件: uniapp 常用原生插件大全 使用方法 在 script…

Python实现打砖块游戏

提供学习或者毕业设计使用,功能基本都有,不能和市场上正式游戏相提比论,请理性对待! 在本文中,我们将使用 Pygame 和 Tkinter 创建一个简单的打砖块游戏。游戏的目标是通过控制挡板来击碎屏幕上的砖块,同时…