内存池的实现

概述:本文介绍用户层内存池的实现

Q:为什么需要内存池?

A:在项目中,用户层通过malloc系统调用申请内存的次数可能很多,每一次malloc系统调用,都会引起用户态——内核态的切换这样的开销对性能的影响是不容忽视的,尤其是当你为了申请一段很小的空间而调用malloc时,性能的损失达到了最大化

Q:什么是内存池?
解决方案:只调用一次malloc

A:只调用一次malloc申请足够大的内存空间,后续需要使用内存时,从已申请的内存中取出一块,这就是内存池的概念

这样就避免了频繁进行malloc系统调用,大大降低了性能损失

内存池的实现

思路:

1.内存池的空间由一次malloc调用分配

2.此时的内存池是一整块连续的内存空间

3.使用时,每次应该分配出一小块(固定大小或任意大小)

4.用户调用malloc申请内存,应该得到一块空间的起始地址

5.用户free归还一块内存时,这块内存需要能被重复使用

为了简要说明原理,本文介绍分配固定大小的内存池版本

后面使用到的二级指针,不懂的朋友可以先移步博主的 数据结构专栏——二级指针 这篇文章

1.内存池结构体定义:

typedef struct mempool_s {int block_size; // 内存池最小单元大小int free_count; // 空余block数量char *free_ptr; // 当前空余的块的地址 char *mem; // 整个内存池的首地址
} mempool_t;

2.初始化,为内存池申请空间:

int mp_init(mempool_t *m, int size) { // 初始化内存池,指定大小if (!m) return -1;if (size < 16) size = 16; // 最小内存池尺寸为 16字节m->block_size = size;m->mem = (char *)malloc(MEM_PAGE_SIZE); // 为内存池分配空间if (!m->mem) return -1;m->free_ptr = m->mem;   // 当前空闲的区域指针m->free_count = MEM_PAGE_SIZE / size;// 二级指针// 将一整块内存抽象为多块:块大小为size,每一块的首地址的前8个字节保存下一块的首地址int i = 0;char *ptr = m->free_ptr;for (i = 0;i < m->free_count; i++) {*(char **)ptr = ptr + size; // 将当前块的首地址的前8个字节保存下一块的首地址ptr += size;}*(char **)ptr = NULL; // 最后一块return 0;
}

3.用户层接口:malloc

void *mp_alloc(mempool_t *m) { // 向内存池申请一块内存if (!m || m->free_count == 0) return NULL; // 如果内存池不存在或没有剩余空间void *ptr = m->free_ptr;m->free_ptr = *(char **)ptr; // 更新free指针,指向下一个空余的内存块m->free_count --;return ptr;
}

4.用户层接口:free

void mp_free(mempool_t *m, void *ptr) {*(char **)ptr = m->free_ptr; // 将即将被回收的块,指向当前空余的块m->free_ptr = (char *)ptr; // 将当前空余的块修改为即将回收的块// 相当于把回收的块插入空余队列的第一个位置,优先分配回收的块m->free_count ++;
}

5.测试函数main

int  main() { // 测试mempool_t m;mp_init(&m, 32);void *p1 = mp_alloc(&m);printf("1: mp_alloc: %p\n", p1);void *p2 = mp_alloc(&m);printf("2: mp_alloc: %p\n", p2);void *p3 = mp_alloc(&m);printf("3: mp_alloc: %p\n", p3);void *p4 = mp_alloc(&m);printf("4: mp_alloc: %p\n", p4);mp_free(&m, p2);void *p5 = mp_alloc(&m);printf("5: mp_alloc: %p\n", p5);return 0;
}

推荐学习 https://xxetb.xetslk.com/s/p5Ibb

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

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

相关文章

工业AI的崛起,中国自主创新的新机遇

我们都知道&#xff0c;互联网已经深刻地改变了我们的生活方式&#xff0c;催生了无数的新型商业模式和创新产业&#xff0c;推动了社会的经济变革。中国在互联网领域的发展取得了举世瞩目的成就&#xff0c;建成了全球规模最大、技术领先的5G网络&#xff0c;互联网应用的普及…

各种网络协议在设计目的、工作方式、应用场景等方面存在显著的区别

各种网络协议在设计目的、工作方式、应用场景等方面存在显著的区别。以下是一些常见网络协议的区别 概述&#xff1a; TCP与UDP&#xff1a; 设计目的&#xff1a;TCP&#xff08;传输控制协议&#xff09;提供面向连接的、可靠的、基于字节流的传输服务。UDP&#xff08;用户…

linux文件编程api: creat

1.基本信息 功能 创建新文件 头文件 #include<fcntl.h> 函数形式 int creat(const char *pathname, mode_t mode); 返回值 如果成功&#xff0c;则返回文件描述符号 如果失败&#xff0c;则返回-1 参数 pathname: 创建的文件名 mode: 新建文件时&#xff0c;文件权限…

Java Web(入门)

Java Web 1. 入门基础 1.1 Java Web简介 Java Web开发是指使用Java技术来创建动态网站或Web应用程序。Java Web开发主要使用Servlet、JSP&#xff08;JavaServer Pages&#xff09;、JavaBeans等技术来实现动态页面和处理业务逻辑。 1.2 环境搭建 为了开发Java Web应用程序…

TypeScript-字面量类型

字面量类型 使用 JS字面量 作为类型对变量进行类型注解&#xff0c;这种类型就是字面量类型&#xff0c;字面量类型比普通的类型更加精确 // 普通number类型&#xff0c;可以赋值任何数值 let count: number count 1 count 2 // 字面量类型100 只能赋值为100 let count: 1…

Django革新者:突破传统,构建下一代Web应用

书接上文 —— 家园建筑师&#xff1a;用Django打造你的Web帝国&#xff0c;从前面的学习中&#xff0c;咱们我们经历了一个完整的Django Web开发之旅&#xff0c;涵盖了从基础概念到高级特性的各个方面&#xff1a; 引言&#xff1a;介绍了企业级Web框架的需求&#xff0c;并概…

牛客NC67 汉诺塔问题【中等 递归 Java/Go/PHP/C++】 lintcode 169 · 汉诺塔

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/7d6cab7d435048c4b05251bf44e9f185 https://www.lintcode.com/problem/169/ 思路 相传在古印度圣庙中&#xff0c;有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上&#xff0c;有三根杆(编号A、B、C…

使用Python操作Jenkins

大家好&#xff0c;Python作为一种简洁、灵活且功能丰富的编程语言&#xff0c;可以与各种API轻松集成&#xff0c;Jenkins的API也不例外。借助于Python中的python-jenkins模块&#xff0c;我们可以轻松地编写脚本来连接到Jenkins服务器&#xff0c;并执行各种操作&#xff0c;…

拌合楼系统开发(二十)解决海康DS-TVL224系列屏幕显示二维码思路

前言&#xff1a; 需求是想在通过程序动态控制显示屏显示二维码&#xff0c;最开始有些担心led这种点阵屏会不会对二维码显示出来后无法识别&#xff0c;实际测时候发现是没问题的。对于显示文字和语音播报&#xff0c;csdn上已经有大神有完整的代码。 海康威视道闸进出口LED屏…

100个 Unity小游戏系列三 -Unity 抽奖游戏专题二 水果机游戏

一、演示效果 二、知识点 2.1 布局 private void CreateItems(){for (int i 0; i < rewardDatas.Length; i){var reward_data rewardDatas[i];GameObject fruitOjb;if (i < itemRoot.childCount){fruitOjb itemRoot.GetChild(i).gameObject;}else{fruitOjb Instant…

数据中台建设方案(Word版源文档)

建设大数据管理中台&#xff0c;按照统一的数据规范和标准体系&#xff0c;构建统一数据采集&#xfe63;治理&#xfe63;共享标准、统一技术开发体系、统一接口 API &#xff0c;实现数据采集、平台治理&#xff0c;业务应用三层解耦&#xff0c;并按照统一标准格式提供高效的…

最新!!2024年上半年软考【中级软件设计师】综合知识真题解析

2024上半年软考考试已经结束了&#xff0c;为大家整理了网友回忆版的软件设计师真题及答案&#xff0c;总共30道题。 上半年考试的宝子们可以对答案预估分数&#xff01;准备下半年考的宝子可以提前把握考试知识点和出题方向&#xff0c;说不定会遇到相同考点的题目&#xff01…

[集群聊天服务器]----(十)Nginx的tcp负载均衡配置--附带截图

接着上文&#xff0c;我们剖析了服务端和客户端的代码&#xff0c;但是单台服务器的并发量是有限的&#xff0c;面对并发量的要求&#xff0c;我们就需要引入Nginx来实现并发量的要求&#xff0c;将用户请求分发到不同的服务器上分担压力&#xff0c;这就是负载均衡。 选择负…

汽车制造业安全有效的设计图纸文件外发系统是什么样的?

在汽车制造的世界里&#xff0c;那些设计图不仅仅是公司智慧的闪光点&#xff0c;更是它们竞争的秘密武器。但问题来了&#xff0c;当公司需要和供应商、合作伙伴频繁交换数据时&#xff0c;怎样安全又高效地发送这些设计图&#xff0c;就成了一个头疼的问题。这篇文章会深挖一…

python常用镜像

#1. 阿里云镜像&#xff1a;https://mirrors.aliyun.com/pypi/simple/ #2. 清华大学镜像&#xff1a;https://pypi.tuna.tsinghua.edu.cn/simple #3. 豆瓣镜像&#xff1a;https://pypi.doubanio.com/simple/ #4. 中科大镜像&#xff1a;https://pypi.mirrors.ustc.edu.cn/simp…

计算机网络——在地址栏输入网址(URL)之后都发生了什么

网址&#xff0c;也叫域名&#xff0c;域名就像一个 IP 地址的可读版本&#xff0c;比如&#xff0c;百度的域名 www.baidu.com&#xff0c;他的 ip 是 110.242.68.3&#xff0c;输入 IP 一样可以跳转到百度搜索的页面&#xff0c;我想没有一个人没去记百度的 IP 吧。其实我们真…

部署Prometheus + Grafana实现监控数据指标

1.1 Prometheus安装部署 Prometheus监控服务 主机名IP地址系统配置作用Prometheus192.168.110.27/24CentOS 7.94颗CPU 8G内存 100G硬盘Prometheus服务器grafana192.168.110.28/24CentOS 7.94颗CPU 8G内存 100G硬盘grafana服务器 监控机器 主机名IP地址系统配置k8s-master-0…

符合车规级漏电流检测的磁通门传感器KTD1100

电动车充电桩 在政策出台后&#xff0c;充电桩类产品按要求需装配B端漏电流检测装置。它可以有效防止充电桩等设备中的漏电流对用户造成危害&#xff0c;保障用户的用电安全。其次&#xff0c;它可以促进充电桩等产品的质量提升&#xff0c;提高市场的公平竞争&#xff0c;让消…

无线领夹麦克风哪个品牌好?本期文章揭秘无线麦克风哪个品牌好用

​在当下这个全民皆为媒体的时代大潮中&#xff0c;视频分享已然成为了引领风尚的指向标。在自媒体领域竞争愈发激烈的态势下&#xff0c;若要在这片广阔海洋中扬帆远航&#xff0c;优秀的作品毫无疑问是吸引观众的关键所在。而想要塑造出这样的卓越之作&#xff0c;除了需要创…

npm 版本号指定标识符

关于依赖的版本 我们可以先来了解依赖的版本 {"dependencies": {"nestjs/common": "^10.0.0","nestjs/core": "^10.0.0",} } 比如我们常见的依赖版本一般长这样&#xff0c;它一般由三部分组成&#xff1a;major.minor.p…