【CS.OS】堆管理算法:不同的堆分配和管理算法

1000.5.CS.OS.1.3-基础-内存管理-堆管理算法-Created: 2024-06-09.Sunday10:41
在这里插入图片描述

文章目录

      • 1 内存分配算法概述
        • 1.1 首次适应(First-Fit)
        • 1.2 最佳适应(Best-Fit)
      • 2 伙伴系统(Buddy System)
    • 3 总结
    • References

在操作系统和程序设计中,内存管理是一个至关重要的环节。不同的堆分配和管理算法,如首次适应(first-fit)、最佳适应(best-fit)和伙伴系统(buddy system),在内存分配和管理中发挥着重要作用。这篇文章将深入探讨这些算法,并通过示例代码展示其实现。

1 内存分配算法概述

内存分配算法用于动态地分配和释放内存,以便程序能够高效地使用系统资源。以下是一些常见的堆分配和管理算法:

1.1 首次适应(First-Fit)

首次适应算法是一种简单且快速的内存分配算法。它从头开始扫描内存分区表,找到第一个足够大的空闲块,并分配给请求的进程。

优点:

  • 快速:由于从头开始扫描,通常能迅速找到合适的空闲块。
  • 简单:实现和理解都较为简单。

缺点:

  • 内存碎片:容易产生外部碎片,导致内存利用率下降。

示例代码:

#include <iostream>
#include <vector>struct Block {int size;bool free;Block(int s) : size(s), free(true) {}
};class FirstFitAllocator {
public:FirstFitAllocator(std::vector<int> blockSizes) {for (int size : blockSizes) {blocks.push_back(Block(size));}}void* allocate(int requestSize) {for (Block& block : blocks) {if (block.free && block.size >= requestSize) {block.free = false;return &block;}}return nullptr; // Allocation failed}void deallocate(void* ptr) {Block* block = static_cast<Block*>(ptr);block->free = true;}private:std::vector<Block> blocks;
};int main() {FirstFitAllocator allocator({100, 500, 200, 300, 600});void* ptr1 = allocator.allocate(150);void* ptr2 = allocator.allocate(100);allocator.deallocate(ptr1);void* ptr3 = allocator.allocate(50);return 0;
}
1.2 最佳适应(Best-Fit)

最佳适应算法通过扫描整个内存分区表,找到最接近请求大小的空闲块进行分配。这种方法尽量减少剩余的空闲块,降低外部碎片的产生。

优点:

  • 内存利用率高:通过分配最接近大小的空闲块,减少了外部碎片。
  • 有效:在内存资源紧张的情况下表现较好。

缺点:

  • 扫描时间长:需要扫描整个内存分区表,可能导致分配时间较长。

示例代码:

#include <iostream>
#include <vector>
#include <limits>struct Block {int size;bool free;Block(int s) : size(s), free(true) {}
};class BestFitAllocator {
public:BestFitAllocator(std::vector<int> blockSizes) {for (int size : blockSizes) {blocks.push_back(Block(size));}}void* allocate(int requestSize) {int bestFitIndex = -1;int minDiff = std::numeric_limits<int>::max();for (int i = 0; i < blocks.size(); ++i) {if (blocks[i].free && blocks[i].size >= requestSize) {int diff = blocks[i].size - requestSize;if (diff < minDiff) {minDiff = diff;bestFitIndex = i;}}}if (bestFitIndex != -1) {blocks[bestFitIndex].free = false;return &blocks[bestFitIndex];}return nullptr; // Allocation failed}void deallocate(void* ptr) {Block* block = static_cast<Block*>(ptr);block->free = true;}private:std::vector<Block> blocks;
};int main() {BestFitAllocator allocator({100, 500, 200, 300, 600});void* ptr1 = allocator.allocate(150);void* ptr2 = allocator.allocate(100);allocator.deallocate(ptr1);void* ptr3 = allocator.allocate(50);return 0;
}

2 伙伴系统(Buddy System)

伙伴系统是一种平衡了首次适应和最佳适应优点的内存分配算法。它将内存分割成大小为2的幂次方的块,当需要分配内存时,会找到最小的满足请求的块。如果块大小过大,会将其分割成两个“伙伴”块,并继续分配。

优点:

  • 内存碎片少:由于采用幂次方块,容易合并相邻空闲块,减少碎片。
  • 分配和释放效率高:通过伙伴系统,分配和释放操作较为高效。

缺点:

  • 内存浪费:有时会由于块大小限制,导致内存浪费。

示例代码:

#include <iostream>
#include <vector>
#include <cmath>class BuddyAllocator {
public:BuddyAllocator(int size) {int n = std::ceil(std::log2(size));maxSize = 1 << n;freeBlocks.resize(n + 1);freeBlocks[n].push_back(0);}void* allocate(int size) {int n = std::ceil(std::log2(size));for (int i = n; i < freeBlocks.size(); ++i) {if (!freeBlocks[i].empty()) {int block = freeBlocks[i].back();freeBlocks[i].pop_back();while (i > n) {--i;int buddy = block ^ (1 << i);freeBlocks[i].push_back(buddy);}return reinterpret_cast<void*>(block * minBlockSize);}}return nullptr; // Allocation failed}void deallocate(void* ptr) {int block = reinterpret_cast<int>(ptr) / minBlockSize;int size = 1;while (true) {int buddy = block ^ size;auto it = std::find(freeBlocks[std::log2(size)].begin(), freeBlocks[std::log2(size)].end(), buddy);if (it == freeBlocks[std::log2(size)].end()) {freeBlocks[std::log2(size)].push_back(block);break;}freeBlocks[std::log2(size)].erase(it);block &= ~size;size <<= 1;}}private:int maxSize;int minBlockSize = 1;std::vector<std::vector<int>> freeBlocks;
};int main() {BuddyAllocator allocator(1024);void* ptr1 = allocator.allocate(100);void* ptr2 = allocator.allocate(200);allocator.deallocate(ptr1);void* ptr3 = allocator.allocate(50);return 0;
}

3 总结

通过了解不同的内存分配算法,我们可以更好地优化程序的内存使用,提高系统的性能和稳定性。希望这篇文章不仅能为你带来技术上的提升,还能激发你对内存管理的兴趣和热情。

在实际项目中,你使用过哪些内存分配算法?它们在你的项目中表现如何?欢迎在评论区分享你的经验和见解,与其他读者互动,共同探讨内存管理的最佳实践。

References

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

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

相关文章

Python | 正则表达式

?:标记?之前的字符为可选. used&#xff1f; d可有可无 *:匹配>0个重复的在*号之前的字符。 ab*c 匹配多个b &#xff1a;匹配>1个重复的号前的字符。&#xff08;至少一个&#xff09; {n,m}&#xff1a;匹配num个大括号之前的字符或字符集 &#xff08;n < num …

算法:101. 对称二叉树

对称二叉树 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false提示&#xff1a; 树中节…

ThreadCache线程缓存

一.ThreadCache整体结构 1.基本结构 定长内存池利用一个自由链表管理释放回来的固定大小的内存obj。 ThreadCache需要支持申请和释放不同大小的内存块&#xff0c;因此需要多个自由链表来管理释放回来的内存块.即ThreadCache实际上一个哈希桶结构&#xff0c;每个桶中存放的都…

目标检测(R-CNN)系列(Pytorch 26)

一 R-CNN 除了之前描述的单发多框检测之外&#xff0c;区域卷积神经网络&#xff08;region‐based CNN或regions with CNN features&#xff0c; R‐CNN&#xff09;(Girshick et al., 2014)也是将深度模型应用于目标检测的开创性工作之一。下面介绍R‐CNN及其一 系列改进方法…

架构设计-web项目中跨域问题涉及到的后端和前端配置

WEB软件项目中经常会遇到跨域问题&#xff0c;解决方案早已是业内的共识&#xff0c;简要记录主流的处理方式&#xff1a; 跨域感知session需要解决两个问题&#xff1a; 1. 跨域问题 2. 跨域cookie传输问题 跨域问题 解决跨域问题有很多种方式&#xff0c;如使用springboot…

cefsharp124.x升级125.x(cef125.0.21/Chromium 125.0.6422.142)

一、版本说明 1.1 依赖关系变化 依赖移除:cef.redist.x64,cef.redist.x86增加新支持chromiumembeddedframework.runtime 旧版本需要移除依赖cef.redist.x64和cef.redist.x86否则会初始化异常。 自版本121.*以后common依赖关系变化 chromiumembeddedframework.runtime.win-x6…

CentOS7 配置Nginx域名HTTPS

Configuring Nginx with HTTPS on CentOS 7 involves similar steps to the ones for Ubuntu, but with some variations in package management and service control. Here’s a step-by-step guide for CentOS 7: Prerequisites Domain Name: “www.xxx.com”Nginx Install…

来腾讯第4天,我已经焦虑昏了啊!

大家好&#xff0c;我是白露啊。 今天在看到一个实习生在抱怨&#xff0c;给我笑惨了。 标题是&#xff1a;“腾讯实习第4天&#xff0c;焦虑昏了”&#xff01; 他写道&#xff1a;“怎么办啊牛爷爷们&#xff0c;什么都不会。业务看不懂&#xff0c;文档看不懂&#xff0c;…

【上海大学计算机组成原理实验报告】七、程序转移机制

一、实验目的 学习实现程序转移的硬件机制。 掌握堆栈寄存器的使用。 二、实验原理 根据实验指导书的相关内容&#xff0c;实验箱系统的程序转移硬件机制在于&#xff0c;当LDPC有效时&#xff0c;如果此时DUBS上的值就是转移的目标地址&#xff0c;则此目标地址被打入PC&am…

k8s概述

文章目录 一、什么是Kubernetes1、官网链接2、概述3、特点4、功能 二、Kubernetes架构1、架构图2、核心组件2.1、控制平面组件&#xff08;Control Plane Components&#xff09;2.1.1、kube-apiserver2.1.2、etcd2.1.3、kube-scheduler2.1.4、kube-controller-manager 2.2、No…

U-Mail:企业邮箱系统安全解决方案

在数字化浪潮的推动下&#xff0c;互联网技术正日新月异&#xff0c;企业的信息通信需求亦随之升华。作为企业沟通的重要媒介&#xff0c;企业邮箱已被广泛应用&#xff0c;然而随着其应用范围的不断扩展&#xff0c;也给企业带来了一系列挑战&#xff1a; 一、统一身份认证管…

大话设计模式解读02-策略模式

本篇文章&#xff0c;来解读《大话设计模式》的第2章——策略模式。并通过Qt和C代码实现实例代码的功能。 1 策略模式 策略模式作为一种软件设计模式&#xff0c;指对象有某个行为&#xff0c;但是在不同的场景中&#xff0c;该行为有不同的实现算法。 策略模式的特点&#…

ui自动化中,selenium进行元素定位,以及CSS,xpath定位总结

几种定位方式 简单代码 from selenium import webdriver import time# 创建浏览器驱动对象 from selenium.webdriver.common.by import Bydriver webdriver.Chrome() # 参数写浏览器驱动文件的路径&#xff0c;若配置到环境变量就不用写了 # 访问网址 driver.get…

springboot+vue前后端分离项目中使用jwt实现登录认证

文章目录 一、后端代码1.响应工具类2.jwt工具类3.登录用户实体类4.登录接口5.测试接口6.过滤器7.启动类 二、前端代码1.登录页index 页面 三、效果展示 一、后端代码 1.响应工具类 package com.etime.util;import com.etime.vo.ResponseModel; import com.fasterxml.jackson.…

基于标定数据将3D LiDAR点云与相机图像对齐(含C++版本代码)

这段C代码演示了如何将Velodyne激光雷达的点云数据投影到相机图像上。该过程涉及以下主要步骤: 读取并解析来自文件的标定数据&#xff0c;包括P2矩阵、R0_rect矩阵和Tr_velo_to_cam矩阵。这些矩阵用于将激光雷达点云从Velodyne坐标系转换到相机坐标系。从二进制文件中读取Velo…

找素数第二、三种方法

文章目录 第一种 &#xff1a;使用标签第二种&#xff1a;本质是方法的分装 第一种 &#xff1a;使用标签 没有使用信号量。break和continue作用范围只是最近的循环&#xff0c;无法控制外部循环。 此时使用标签 对外部循环进行操作。 package com.zhang; /* 找素数 第二种方…

MySQL—多表查询—外连接

一、引言 学到内连接&#xff0c;它是查询的数据两张表交集的部分。而接下来看看外连接。 外连接查询语法&#xff1a;&#xff08;分为两种&#xff09; 1、左外连接 语法结构&#xff1a; 表1 LEFT [OUTER] JOIN 表2 ON 条件 ...; ( ... left out join on ...) 注意&#x…

三、安全工程练习题(CISSP)

1.三、安全工程练习题(CISSP)

WordPress 高级缓存插件 W3 Total Cache Pro 详细配置教程

说起来有关 WordPress 缓存插件明月已经发表过不少文章了,但有关 W3 Total Cache Pro 这个 WordPress 高级缓存插件除了早期【网站缓存插件 W3 Total Cache,适合自己的才是最好的!】一文后就很少再提及了,最近因为明月另一个网站【玉满斋】因为某些性能上的需要准备更换缓存…

java —— 线程(一)

一、进程与线程 一个进程可以包含一个以上的线程&#xff0c;CPU 时间片切换的基本单位是线程。 二、创建线程 &#xff08;一&#xff09;继承 Thread 类 public class Task extends Thread{Override //重写run方法public void run(){System.out.pr…