malloc的底层原理和流程

目录

  • 一、malloc的内存申请方式
  • 二、malloc的内存池管理
      • 1、分级内存池
      • 2、内存块信息
      • 3、内存块合并
      • 4、内存块分割
  • 三、brk的内存分配过程
      • 1、空闲链表
      • 2、sbrk
  • 四、malloc的缺陷

前言:从malloc的内存方式、内存池管理、brk系统调用过程这三个点,讲述malloc系统调用的底层原理和流程。

一、malloc的内存申请方式

malloc申请内存有两种,申请小于128KB的内存是用brk系统调用,申请大于128KB就是用mmap的匿名映射。(brk和mmap申请的都是懒分配内存,只有真正访问时才分配物理内存)

  • 为什么要有brk方式

mmap是系统调用,频繁的系统调用会让CPU性能下降。所以就通过brk系统调用,每次malloc申请内存时,brk会给malloc分配比所需内存更大的内存池,然后malloc后面就可以自己操作内存池来申请或释放内存,而无需再调用系统调用。所以对于brk方式的malloc,使用free并不会直接将内存归还系统,而是留在内存池等进程结束才归还。

二、malloc的内存池管理

注1:只有brk方式申请的内存会有内存池机制,mmap并没有这个机制。
注2:下面只是简单说明malloc内存管理最主要的机制,省略了一些其他的机制或细节

1、分级内存池

malloc使用分级线程池,将不同大小的内存块分为不同等级,每个等级有对应的一个空闲链表来管理。malloc会根据每次请求的大小来选择合适的级别,从链表中分配内存。链表的遍历可以是从头到尾找到第一个满足请求的大小进行分配,也可以是找到大小最接近的块来分配。

2、内存块信息

在每块内存的开头处会有对应的内存块信息,包括内存块的大小、空闲链表的下一块内存的指针、以及内存是否被分配。free调用就是根据这里来得知释放内存的大小。

3、内存块合并

当内存块被释放时,如果相邻块也是空闲的,malloc会进行块合并来减少内存碎片。在高频率的内存分配和释放场景中,这个操作会影响性能

4、内存块分割

当 malloc在空闲链表中找到一个比请求大小大的空闲块时,它可能会将这个块分割成两部分,一部分分配给请求的内存,另一部分仍然保持空闲状态。但这个频繁的分割操作可能会导致小的内存块散布在内存中,增加内存碎片化

三、brk的内存分配过程

对于malloc,brk每次以页为单位来给malloc分配内存池,之后让malloc自己管理和操作内存池的内存,直到内存池不够了再调用brk来扩充内存池。brk分配内存的大致过程就是将堆区内存向上扩展,具体流程这里以xv6操作系统为例(一个类Unix的简单系统)。注:看懂这里需要有一定的页表基础

1、空闲链表

和malloc的内存池管理方式类似,xv6系统在每个空闲页面的内存开头处存放一个run结构体,该结构体存储着一个指向下个空闲页起始地址的指针next。由于run的地址和页面地址相同,所以xv6可以通过遍历run链表来找到所有空闲页。这个run链表叫做allocator分配器。

2、sbrk

sbrk是xv6系统中的系统调用,用于给进程增加或减少堆区内存。分配内存主要就是做两件事:1、从空闲链表中删除一张空闲内存页并返回给进程;2、把内存页的虚拟地址和物理地址的映射关系写到页表PTE上并设置标志位。减小内存同理,主要就是:1、把对应页表项清空(设置PTE_V);2、根据该页面的物理地址创建run结构体并插入空闲链表。

四、malloc的缺陷

1、不支持多线程环境;2、由于内存块分割操作,频繁malloc会导致内存碎片化;3、由于内存块合并操作,频繁free会一直触发影响性能。

解决方法:自己实现一个内存池来替代malloc

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

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

相关文章

2054. 骑马修栅栏

代码 #include<bits/stdc.h> using namespace std; int mp[505][505]; queue<int> ans; int du[505]; int n0,m,u,v;void dfs(int i) {for(int j1;j<n;j){if(mp[i][j]>1){mp[i][j]--;mp[j][i]--;dfs(j);}}ans.push(i); } int main() {cin>>m;for(int …

Linux安装Miniconda3

Linux安装Miniconda3 安装步骤相关知识 安装步骤 官方安装指南。 mkdir -p ~/miniconda3 wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3 rm ~/miniconda…

WordPress简约响应式个人博客Kratos主题

Kratos主题基于Bootstrap和Font Awesome的WordPress一个干净&#xff0c;简单且响应迅速的博客主题&#xff0c;Vtrois创建和维护&#xff0c;主题设计简约友好&#xff0c;并且支持响应式&#xff0c;自适应访问&#xff0c;简seo单大方的主页构造&#xff0c;使得博客能在臃肿…

(十六)Flink 状态管理

目录 状态类型 Keyed State Keyed State 分类 状态有效期(TTL) 过期数据的清理 Operator State Broadcast State 状态存储 State Backends 分类 设置 State Backend RocksDB State Backend 详解 在 Flink 架构体系中,状态(State)计算是其重要的特性之一。状态用…

8.20T3 无损加密(线性代数转LGV+状压dp+高维前缀和)

http://cplusoj.com/d/senior/p/NODSX2301C 对于式子&#xff1a; 这个神秘的线性代数形式比较难处理&#xff0c;但我们可以考虑其组合意义。行列式现存的可用组合意义之一就是LGV&#xff08;矩阵式不太可用&#xff09; 先把原先的矩阵转化为一个有向图。现在我们要构造一…

ArcGIS如何将投影坐标系转回为地理坐标系

有时候两个数据&#xff0c;一个为投影坐标系&#xff0c;另一个为地理坐标系时&#xff0c;在GIS软件中位置无法叠加到一起&#xff0c;这需要将两个或多个数据的坐标系统一&#xff0c;可以直接将地理坐标系的数据进行投影&#xff0c;或将投影坐标系转为地理坐标系。下面介绍…

自养号测评技术:如何挑选适合的IP环境方案

市面上的IP服务及常见问题 当前市场上常见的IP服务包括911、Luminati、Google Fi、TM流量卡、Socks专线等。这些服务在为用户提供网络代理或VPN服务时&#xff0c;常会遇到以下主要问题&#xff1a; 1. 高负载与重复率高&#xff1a;由于使用人数众多&#xff0c;导致网络拥堵…

【jvm】栈是否存在垃圾回收

目录 一、栈的特点1.1 栈内存分配1.2 栈的生命周期1.3 垃圾回收不直接涉及 二、堆与栈的区别三、总结 一、栈的特点 1.1 栈内存分配 1.栈内存分配是自动的&#xff0c;不需要程序员手动分配和释放。 2.每当一个方法被调用时&#xff0c;JVM就会在这个线程的栈上创建一个新的栈…

移动端爬虫学习记录

免责声明 本文旨在探讨移动端爬虫技术的应用和挑战&#xff0c;仅供教育和研究用途。请确保在合法合规的框架内使用爬虫技术&#xff0c;遵循相关法律法规和网站的使用条款。作者不对因使用本文内容而产生的任何法律或安全问题承担责任。 1、初识移动端爬虫 学习移动端爬虫的原…

docker映射了端口,宿主机不生效

1、问题产生原因 docker run -d --name my-redis -p 6379:6379 -v /usr/redis.conf:/usr/local/etc/redis/redis.conf team-redis:3.2 redis-server /usr/local/etc/redis/redis.conf 这容器跑起来了&#xff0c;端口6379没用。搞的我一直怀疑哪里出错了&#xff0c;查看配置…

继承与构造函数与析构函数

一 #include<iostream> using namespace std; class father { public:father(){cout << "father无参构造函数" << endl;}father(int x):fa(x){cout << "father单参构造函数" << endl;}~father() {cout << "fath…

【docker compose 部署和 go 热部署工具fresh】

文章目录 docker-compose.yml 文件配置得很全面&#xff0c;以下是一些注释安装 fresh配置 fresh注意事项 docker-compose.yml 文件配置得很全面&#xff0c;以下是一些注释 version: 3 services:# MySQL 服务geekai-mysql:image: registry.cn-shenzhen.aliyuncs.com/geekmast…

计算机视觉(CV)技术的优势和挑战。

计算机视觉&#xff08;CV&#xff09;技术在许多领域中具有广泛的应用&#xff0c;并且具有一些优势和挑战。 优势&#xff1a; 1. 高效性&#xff1a;CV技术能够快速处理大量的图像和视频数据&#xff0c;以实现实时的分析和决策。 2. 自动化&#xff1a;CV技术可以自动化地…

CSS的table显示值:布局艺术的幕后推手

CSS的table显示值&#xff1a;布局艺术的幕后推手 摘要 CSS&#xff08;层叠样式表&#xff09;是构建网页布局的核心技术之一。display: table;是CSS中一个强大的属性&#xff0c;它允许元素表现得像HTML表格一样。本文将深入探讨table显示值如何影响元素的布局&#xff0c;…

C++ QT 单例模式

在 C 中&#xff0c;使用 Qt 框架实现单例模式可以确保一个类只有一个实例&#xff0c;并提供一个全局访问点。以下是一个简单的 C Qt 单例模式实现示例。 1. 饿汉式单例模式 饿汉式单例模式在类加载时就初始化单例对象。 // MySingleton.h #ifndef MYSINGLETON_H #define M…

Kakfa的核心概念-Replica副本(kafka创建topic并指定分区和副本的两种方式)

Kakfa的核心概念-Replica副本&#xff08;kafka创建topic并指定分区和副本的两种方式&#xff09; 1、kafka命令行脚本创建topic并指定分区和副本2、springboot集成kafka创建topic并指定分区和副本2.1、springboot集成kafka2.1.1、springboot集成kafka创建topic并指定5个分区和…

VScode 连接远程服务器

1、 2、 3、免密登录 1、本地生成密钥 ssh-keygen2、生成的密钥默认在 C:\Users\***\.ssh\ 中3、将私钥 C:\Users\***\.ssh\id_rsa 添加到上面的配置文件中的 IdentityFile 项内4、将公钥 C:\Users\***\.ssh\id_rsa\id_rsa.pub 拷贝到远程 ~/.ssh/authorized_keys 中 4、远程…

【精选】基于django柚子校园影院(咨询+解答+辅导)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

Golang | Leetcode Golang题解之第371题两整数之和

题目&#xff1a; 题解&#xff1a; func getSum(a, b int) int {for b ! 0 {carry : uint(a&b) << 1a ^ bb int(carry)}return a }

python | Python集成学习和随机森林算法

本文来源公众号“python”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;Python集成学习和随机森林算法 集成学习是一种通过组合多个模型来提高预测性能的机器学习方法。它通过将多个弱学习器的结果结合起来&#xff0c;形成一个…