深入讲解内存分配函数 malloc 原理及实现 任何一个用过或学过C的人对 malloc 都不会陌生。大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉。但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至把malloc当做操作系统所提供的系统调用或C的关键字。 实际上,malloc只是C的标准库中提供的一个普通函数,而且实现malloc的基本思想并不复杂,任何一个对C和操作系统有些许了解的程序员都可以很容易理解。 这篇文章通过实现一个简单的 malloc 来描述 malloc 背后的机制。当然与现有 C 的标准库实现(例如glibc)相比,我们实现的 malloc 并不是特别高效,但是这个实现比目前真实的 malloc 实现要简单很多,因此易于理解。重要的是,这个实现和真实实现在基本原理上是一致的。 这篇文章将首先介绍一些所需的基本知识,如操作系统对进程的内存管理以及相关的系统调用,然后逐步实现一个简单的malloc。为了简单起见,这篇文章将只考虑x86_64 体系结构,操作系统为Linux。 好文推荐: 万字讲解你写的代码是如何跑起来的? 什么是Linux内核,如何搞懂Linux内核?(Linux内核学习笔记合集来了!) 字节终面:CPU 是如何读写内存的? 全网最牛Linux内核分析–Intel CPU体系结构 一文让你读懂Linux五大模块内核源码,内核整体架构设计(超详细) 嵌入式前景真的好吗?那有点悬! 一文教你如何使用GDB+Qemu调试Linux内核 Linux内核必读五本书籍(强烈推荐) 全网独一无二Linux内核Makefle系统文件详解(一)(纯文字代码) 带你深度了解Linux内核架构和工作原理! 如何读懂GDB底层实现原理(从这几点入手~) 一文彻底理解Memory barrier(内存屏障) 一篇文带你搞懂,虚拟内存、内存分页、分段、段页式内存管理(超详细) 1 什么是malloc 在实现malloc之前,先要相对正式地对malloc做一个定义。 根据标准C库函数的定义,malloc具有如下原型: 这个函数要实现的功能是在系统中分配一段连续的可用的内存,具体有如下要求:malloc分配的内存大小至少为size参数所指定的字节数malloc的返回值是一个指针,指向一段可用内存的起始地址多次调用malloc所分配的地址不能有重叠部分,除非某次malloc所分配的地址被释放掉malloc应该尽快完成内存分配并返回(不能使用NP-hard[1]的内存分配算法)实现malloc时应同时实现内存大小调整和内存释放函数(即realloc和free) 对于malloc更多的说明可以在命令行中键入以下命令查看: 2 预备知识 在实现malloc之前,需要先解释一些Linux系统内存相关的知识。 2.1 Linux内存管理 2.1.1 虚拟内存地址与物理内存地址 为了简单,现代操作系统在处理内存地址时,普遍采用虚拟内存地址技术。即在汇编程序(或机器语言)层面,当涉及内存地址时,都是使用虚拟内存地址。采用这种技术时,每个进程仿佛自己独享一片2N字节的内存,其中N是机器位数。例如在64位CPU和64位操作系统下,每个进程的虚拟地址空间为264Byte。 这种虚拟地址空间的作用主要是简化程序的编写及方便操作系统对进程间内存的隔离管理,真实中的进程不太可能(也用不到)如此大的内存空间,实际能用到的内存取决于物理内存大小。 由于在机器语言层面都是采用虚拟地址,当实际的机器码程序涉及到内存操作时,需要根据当前进程运行的实际上下文将虚拟地址转换为物理内存地址,才能实现对真实内存数据的操作。这个转换一般由一个叫MMU[2](Memory Management Unit)的硬件完成。 2.1.2 页与地址构成 在现代操作系统中,不论是虚拟内存还是物理内存,都不是以字节为单位进行管理的,而是以页(Page)为单位。一个内存页是一段固定大小的连续内存地址的总称,具体到Linux中,典型的内存页大小为4096Byte(4K)。 所以内存地址可以分为页号和页内偏移量。下面以64位机器,4G物理内存,4K页大小为例,虚拟内存地址和物理内存地址的组成如下:







2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/84115.html

