malloc函数内存分配原理

malloc 是一个库函数,在<stdlib.h> 头文件中,是在程序的运行时库(Runtime Library)中实现的。这个函数主要用于在程序运行期间动态地分配内存。当在 C 语言程序中使用 malloc 时,实际上是在调用运行时库提供的一个函数,该函数会尝试从进程可用的内存池中分配一块大小适合的内存区域,并返回一个指向这块内存的指针。

malloc分配内存的原理:

1. 初始化

第一次调用 malloc 时,它会初始化一个内存池。这个内存池通常是通过向操作系统请求一块连续的内存区域来创建的。在 Unix-like 系统中,这通常通过 sbrk 系统调用来实现;而在 Windows 中,则可能通过 VirtualAlloc API 来实现。(如果分配的内存比较大,则可能会用mmap方式)

2. 内存池管理

malloc 维护一个内存池,内存池中包含已经分配出去的内存块以及空闲的内存块。通常,malloc 使用某种数据结构(如链表、二叉树或其他高效的数据结构)来跟踪这些内存块的状态(已分配/空闲)和大小。

3. 分配内存

当程序调用 malloc(size_t size) 请求分配内存时,malloc 需要在内存池中找到一个足够大的空闲块来满足请求。如果内存池中有足够的连续空闲空间,malloc 会从这个空闲块中分割出一块大小为 size 的内存,并返回一个指向这块内存的指针。

4. 内存对齐

malloc 会确保返回的内存地址是按照平台要求对齐的,比如在 x86 架构中,内存地址通常需要对齐到 8 字节或 16 字节边界,以优化内存访问性能。(不是所有平台都是这样)

5. 扩展内存池

如果内存池中的空闲块不足以满足新的请求,malloc 会尝试扩展内存池。这通常通过再次调用 sbrk 或 mmap 来实现,从操作系统获取更多的内存。新增的内存会被添加到内存池中,并可用于后续的内存分配请求。

6. 内存碎片处理

在多次分配和释放内存之后,内存池中可能会出现大量的小块空闲内存,这些小块之间不连续,导致内存碎片。malloc 可能会尝试合并相邻的小块空闲内存,使其成为一个较大的空闲块,从而减少内存碎片。

7. 释放内存

当程序不再需要某块内存时,应通过调用 free 函数来释放它。free 会将这块内存标记为空闲,并可能尝试与相邻的空闲块进行合并,以减少内存碎片。

8. 特殊情况处理

如果 malloc 发现无法从操作系统获取更多的内存来满足请求,它会返回 NULL,表示内存分配失败。

malloc分配的内存是虚拟内存还是物理内存?

malloc 分配的内存通常是虚拟内存。这是因为现代操作系统使用了虚拟内存机制,将进程的地址空间与实际物理内存区分开来。

既然是虚拟内存,那么分配的虚拟内存会和物理内存进行映射吗?

malloc 分配内存后,并不会立即为新分配的内存区域映射物理内存。相反,操作系统通常采用一种叫做“延迟分配”或“按需分页”(demand paging)的技术。这意味着在新分配的内存块中,只有当程序试图访问其中的数据时,才会触发一个分页错误(page fault),此时操作系统才会实际分配物理内存给这个虚拟地址,并建立虚拟地址到物理地址的映射。

这种策略有几个好处:

1.节省资源:如果分配的内存没有立即使用,那么就没有必要浪费物理内存。

2.提高效率:只有当内存真正被使用时才分配,可以避免不必要的内存分配和管理开销。

3.内存复用:操作系统可以复用未被实际使用的虚拟内存地址空间,直到它们被访问为止。

所以,malloc 分配的内存块在初始状态下一般是未映射到任何物理内存的。只有当程序开始读取或写入这部分内存时,操作系统才会分配物理内存并完成映射。这种机制使得内存管理更加灵活和高效。

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

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

相关文章

【面试八股总结】GMP模型

GMP概念 G&#xff08;Goroutine&#xff09;&#xff1a;代表Go协程&#xff0c;是参与调度与执行的最小单位。 存储Goroutine执行栈信息、状态、以及任务函数等。G的数量无限制&#xff0c;理论上只受内存的影响。Goroutines 是并发执行的基本单位&#xff0c;相比于传统的线…

Redis集群知识及实战

1. 为什么使用集群 在哨兵模式中&#xff0c;仍然只有一个Master节点。当并发写请求较大时&#xff0c;哨兵模式并不能缓解写压力。我们知道只有主节点才具有写能力&#xff0c;那如果在一个集群中&#xff0c;能够配置多个主节点&#xff0c;是不是就可以缓解写压力了呢&…

sourcetree配置ssh连接gitee

使用PuttyGen.exe生成的公钥私钥格式和git文档方法生成的不一样&#xff0c; SSH 公钥设置 | Gitee 帮助中心 gitee方法生成的公钥类似&#xff1a; ssh-ed25519 AAAA***5B Gitee SSH Key PuttyGen.exe生成的&#xff1a; 公钥 ---- BEGIN SSH2 PUBLIC KEY ---- Comment:…

【新手/小白教程】打开一个vue项目的前置准备,nvm安装指定版本node

目录 一、前言二、nvmnvm介绍nvm下载与安装1. 官网下载 nvm 包2. 安装 nvm-setup.exe3. 配置路径和下载镜像4. 检查nvm是否安装完成5. 错误情况 三、nodenode版本查看node命令 一、前言 在换新电脑的时候总是需要把所有东西重新安装配置&#xff0c;这篇用来记录一下打开一个v…

【云原生监控】Prometheus之PushGateway

Prometheus之PushGateway 文章目录 Prometheus之PushGateway介绍作用资源列表基础环境一、部署PushGateway1.1、下载软件包1.2、解压软件包1.3、编辑配置systemctl启动文件1.4、创建日志目录1.5、加载并启动1.6、监控端口1.7、访问PushGateway 二、 配置Prometheus抓取PushGate…

瓦工交底你家做了吗?真的很重要

有一个工地开始贴瓷砖&#xff0c;和业主约着一块去现场瓦工交底&#xff0c;业主买的瓷砖很有意思      先说一下为什么瓦工交底&#xff0c;瓦工包含的有包下水管&#xff0c;做防水贴墙砖和地砖。      瓦工交底最主要的就是确定墙砖和地砖的排版方式。      如…

如何借助ChatGPT提升论文质量:实战指南

在学术写作的过程中,非英语母语人士经常面临诸多挑战,尤其是当论文要提交给国际期刊时,语言规范和表达逻辑成为了必须克服的障碍。本文将通过实例详细解析如何利用ChatGPT来润色论文,使其达到发表级别的标准。 一、优秀学术论文的写作特点 要让学术论文在国际期刊上发表,…

IP协议及相关特性

IP协议负责地址管理和路由选择。它的组成为&#xff1a; 接下来我们将对其中较重要的部分进行介绍。 4位版本&#xff1a;这里的四位版本只有两个取值 分别为IPv4和IPv6&#xff0c;这两个额分别为不同的IP协议&#xff0c;但是现在主流的还是IPv4但是近年来IPv6在中国的普及率…

OpenHarmony(鸿蒙南向开发)——标准系统方案之瑞芯微RK3566移植案例(上)

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ OpenHarmony&#xff08;鸿蒙南向开发&#xff09;——轻量系统STM32F407芯片移植案…

Java语言程序设计基础篇_编程练习题*18.28 (非递归目录大小)

目录 题目&#xff1a;*18.28 (非递归目录大小) 习题思路 代码示例 输出结果 题目&#xff1a;*18.28 (非递归目录大小) 不使用递归改写程序清单18-7 习题思路 &#xff08; getSize方法&#xff09; 创建一个变量表示总共的大小。传入路径&#xff0c;创建File文件。创建A…

LeeCode打卡第二十九天

LeeCode打卡第二十九天 第一题&#xff1a;岛屿数量&#xff08;LeeCode第200题&#xff09;: 给你一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的的二维网格&#xff0c;请你计算网格中岛屿的数量。岛屿总是被水包围&#xff0c;并且每座岛屿只…

【Elasticsearch】-图片向量化存储

需要结合深度学习模型 1、pom依赖 注意结尾的webp-imageio 包&#xff0c;用于解决ImageIO.read读取部分图片返回为null的问题 <dependency><groupId>org.openpnp</groupId><artifactId>opencv</artifactId><version>4.7.0-0</versio…

docker存储

docker分层结构 如图所示&#xff0c;容器是由最上面可读可写的容器层&#xff0c;以及若干个只读镜像层组成&#xff0c;创建容器时&#xff0c;容器中的 数据都来自镜像层。这样的分层机构最大的特点是写时复制&#xff1a; 1、容器中新生成的数据会直接存放在容器层&#xf…

SAP 生产订单报工自动入库的几种处理方法

SAP 生产订单报工自动入库的几种处理方法 一、自动入库的功能与原理自动入库的核心机制包括:二、配置自动入库1. 控制关键字(Control Key)中的自动入库标志2. 生产订单类型设置三、自动入库的流程四、自动入库的优势五、适用场景六、业务场景七、系统配置点八、前台操作演示…

移动技术开发:登录注册界面

1 实验名称 登录注册界面 2 实验目的 掌握基本布局管理器的使用方法和基本控件的使用方法 3 实验源代码 布局文件代码&#xff1a; <?xml version"1.0" encoding"utf-8"?><LinearLayoutxmlns:android"http://schemas.android.com/apk/…

在Windows 7上安装Redis

1、下载Redis安装包‌&#xff1a; 首先&#xff0c;从Redis的官方网站或可信的第三方资源下载Redis的Windows版本安装包。确保下载与你的Windows 7系统兼容的版本。 2、解压安装包‌&#xff1a; 将下载的Redis安装包解压到你选择的目录&#xff0c;例如F:\Redis\redis-win…

关于文件操作

1. 为什么使⽤⽂件&#xff1f; 如果没有⽂件&#xff0c;我们写的程序的数据是存储在电脑的内存中&#xff0c;如果程序退出&#xff0c;内存回收&#xff0c;数据就丢失 了&#xff0c;等再次运⾏程序&#xff0c;是看不到上次程序的数据的&#xff0c;如果要将数据进⾏持久…

栈和队列的算法题目(C语言)

1. 括号匹配问题 20. 有效的括号 - 力扣&#xff08;LeetCode&#xff09; 利用栈后入先出的特性解题 1.判断字符串是否为空 为空返回 2.创建栈&#xff0c;遍历字符串 第一个字符是左括号的情况&#xff1a;入栈->继续遍历下一个字符 第一个字符是右括号的情况&#xf…

高等数学 3.3 泰勒公式

泰勒&#xff08;Taylor&#xff09;中值定理1 如果函数 f ( x ) f(x) f(x) 在 x 0 x_0 x0​ 处具有 n n n 阶导数&#xff0c;那么存在 x 0 x_0 x0​ 的一个邻域&#xff0c;对于该领域内的任一 x x x &#xff0c;有 f ( x ) f ( x 0 ) f ′ ( x 0 ) ( x − x 0 ) f…

CAD图1

文章目录 选择直线工具选择圆形选中圆形 选择直线工具 画一条十字中心线 选择圆形 以十字中心为起点画一个半径为 53 的圆形 选中圆形 选中圆形&#xff0c;捕捉右侧圆形焦点