03-系统篇-内存碎片

news2025/1/21 15:26:48

一.常见的malloc内存分配原理

1内存分配原理
linux中应用层动态分配内存一般是用的malloc函数,而malloc在glibc中实现时,是用sbrk()来分内存.
在前面的章节中,我们了解到了堆的概念,堆在内存中,是一断连续的内存,并且上往上增长的,而sbrk()的作用是根据指定的size大小,对堆末尾指针进行往上移动或往下移动,从而实现内存的分配与释放。
size>0   分配内存,size<0   释放内存

2常见malloc和free内存管理逻辑
操作系统的堆内存是连续的,而我们释放内存时,只能对堆末尾的内存进行释放,由于先分配的内存并不一定会先释放,因而,通过sbrk()下移来释放内存在实际中存在问题。
在malloc分配内存时,分配长度=header+用户需要的大小size,header是一个链表节点,包含此段内存是否空闲,此段内存大小,下一个内存的指针。
struct header_t{
     size_t size;
     unsigned int is_free;
     struct header_t *next;
}
若我们调用了free函数,先确认要释放的内存是否在堆的末尾,若在堆末尾,直接操作系统释放,若不在末尾就将is_free;标为空闲,下次使用。
而下一次malloc时,先找一下已存在有链表中,是否有空闲的并且大小合适的内存分配,若有,直接使用,若存在的空闲内存不够大,再调用sbrk()进行分配。

二.内存池原理

实际系统中,由于malloc和free分配内存大小或者分配与释放的时机并不确定,加上内存本身而言就是线性结构,因而肯定会存在正在使用的内存之间有一些内存空闲,但使用不了,这种小的空闲的内存,叫做内存碎片,随着系统分配和释放的频繁,内存碎片会越来越多。
为了减少内存碎片的产生,本节描述了常见解决内碎片的方法,也就是内存池。下面介绍常见的内存池(Apache)的结构。
(1)内存单元结点
struct apr_memnode_t {
  apr_memnode_t*next;           /**< next:指向下一个结点的指针; */
    apr_memnode_t**ref;           /**< 本结点自身 */
    apr_uint32_t  index;              /**< 结点的大小 */
    apr_uint32_t  free_index;       /**< 内存块中未被占用的空间 */
    char         *first_avail;          /**< 可用空间开始位置的指 */
    char         *endp;                 /**< 可用空间结尾位置的指针 */
};

(2)空闲内存管理结点
struct apr_allocator_t {
    apr_uint32_t        max_index;   //free指针数组的最大内存块链表下标
    apr_uint32_t        max_free_index;  //内存分配器所能容纳的最大内存空间数值
    apr_uint32_t        current_free_index;  //内存分配器中还能接收的空间大小
    apr_pool_t          *owner;    //属于哪个内存池
    apr_memnode_t  *free[MAX_INDEX];  //指向一组链表的头结点, MAX_INDEX为20
};

(3)内存池结点
struct apr_pool_t {
    ……
    apr_allocator_t      *allocator;  //空闲内存管理
    apr_memnode_t   *active;//正在使用的内存链表
    ……
};


内存池由上述(1)、(2)、(3)三个节点所构成,下面讲述一下原理。
 

如上图所示,首先内存池结点有两个主要成员,一个是空闲内存管理节点allocator。另外一个是active链表。
allocator可以理解成此内存池剩余的空间,而active表示此内存池正在运行的空间。

1.active:由上图可以知道active是由apr_memnode_t结构体组成的链表,当用户要分配内存时,比如分配内存的大小是size,内存池实际会分配total_size = sizeof(apr_memnode_t)+size,total_size为结构体加上用户需要使用的内存大小。若其中在分配内存时结构体中的index可以取值为0-20,MAX_INDEX为20.   分配内存时,最小分配内存为8K(对应该index=1),超过8K后会以4K为单位累计分配内存,malloc_size = (index-1)*4K+8K  (1 <= index <= 20),因而分配内存的取值最小8K,最大84K,粒度为4K。

若要分配的内存大于84K时,对应的index取值为0。    total_size在哪一个区间,就会对应的分配多少内存从而锁定出对应的index。

2.allocator:由上图可以知道allocator对应apr_allocator_t管理器,其中free是一个数组链表,free的下标的索引就是对应的index,apr_allocator_t管理器是管理空闲内存的,也就是暂时没有使用的内存,根据index可以将空闲的内存放在对应free[index]的所在链表中,从而实现了空闲内存的管理。

3.用户要分配内存,首先可以确认分配内存的index, 然后在allocator管理器查看有没空闲内存,若存在空闲内存,则将空闲的apr_memnode_t 内存节点放在active链表,若没有空闲内存,则从系统中malloc内存。

同样用户释放内存,可以将apr_memnode_t 内存节点从active链表改到allocator管理器上并将内存结点置为空闲。

4.那什么时候将内存返还给系统呢?

(1).整个内存池注销时,所有的内存会一次性全部返还free给系统。

(2).另外需要分配的内存大于apr_allocator_t ->max_free_index时,管理器会在此块内存使用完后,直接还给系统,而不放allocator管理器。 

另外基础篇06-基础篇-缓存与内存泄露讨论的环形缓存也是一种减少内存碎片的办法,内存碎片的解决,实际上就是减少频繁的malloc和free。

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

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

相关文章

适应度函数

23个基准测试函数 优化算法常用的适应度函数23个基准测试函数的图像python版code将以上代码打包为exe 优化算法常用的适应度函数 23个基准测试函数的图像 python版code 将23个基准测试函数封装成python库&#xff0c;并进行实例化、调用绘图函数。下面代码只需根据提示打印&am…

算法通关村18关 | 透析回溯的

回溯有清晰的解题模板&#xff0c; void backtracking(参数){if (终止条件){存放结果;return;}for (选择本层中的集合元素&#xff08;画成树&#xff0c;就是树节点孩子的大小) {处理节点;backtracking();回溯&#xff0c;撤销处理结果;}} 1. 从N叉树说起 在回溯之前&#x…

时序分解 | MATLAB实现ICEEMDAN+SE改进的自适应经验模态分解+样本熵重构分量

时序分解 | MATLAB实现ICEEMDANSE改进的自适应经验模态分解样本熵重构分量 目录 时序分解 | MATLAB实现ICEEMDANSE改进的自适应经验模态分解样本熵重构分量效果一览基本介绍程序设计参考资料 效果一览 基本介绍 ICEEMDANSE改进的自适应经验模态分解样本熵重构分量 包括频谱图 避…

配置Xftp绕过跳板机直连内网环境

一、需求说明 因现场环境限制&#xff0c;现在只有一台管理主机可连入内网环境&#xff0c;但因现在需要传入大量数据到内网环境&#xff0c;二管理主机的存储又无法满足需求&#xff0c;rz和sz命令又有传输大小限制&#xff0c;因此&#xff0c;我们来看下如何配置【隧道】实现…

Win10如何找回图片查看器

近期有小伙伴反映在将Win10升级之后发现电脑自带的图片查看器没有了&#xff0c;这是怎么回事&#xff0c;该怎么找回呢&#xff0c;下面小编就给大家详细介绍一下Win10找回图片查看器的方法&#xff0c;有需要的小伙伴快来和小编一起阅读看看吧。 win10找回windows照片查看器…

日志平台搭建第三章:Linux安装logstash

相关链接 项⽬主⻚&#xff1a; https://www.elastic.co/cn/downloads/logstash 下载地址&#xff1a; wget https://artifacts.elastic.co/downloads/logstash/logstash-7.5.1.tar.gz 官网下载可能比较慢&#xff0c;下面提供下载地址 百度云链接&#xff1a;https://pan.…

【Linux】对进程概念的理解

一丶进程概念 进程定义 进程是一个具有一定独立功能的程序在一个数据集合上依次动态执行的过程。进程是一个正在执行的程序的实例&#xff0c;包括程序计数器、寄存器和程序变量的当前值。 进程特征 1.进程依赖于程序运行而存在&#xff0c;进程是动态的&#xff0c;程序是…

生成树协议 STP(spanning-tree protocol)

一、STP作用 1、消除环路&#xff1a;通过阻断冗余链路来消除网络中可能存在的环路。 2、链路备份&#xff1a;当活动路径发生故障时&#xff0c;激活备份链路&#xff0c;及时恢复网络连通性。 二、STP选举机制 1、目的&#xff1a;找到阻塞的端口 2、STP交换机的角色&am…

UG\NX CAM二次开发 设置工序毛坯 UF_CAMGEOM_append_items

文章作者:代工 来源网站:NX CAM二次开发专栏 简介: UG\NX CAM二次开发 设置工序毛坯 UF_CAMGEOM_append_items 效果: 代码: static int init_proc(UF_UI_selection_p_t select, void* user_data) { int errorCode = 0; int num_triples = 1; UF_UI_mask_t mas…

JavaScript设计模式(五)——发布订阅模式、桥接模式、组合模式

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

Rokid Jungle--Max pro

介绍和功能开发 YodaOS-Master操作系统&#xff1a;以交换计算为核心&#xff0c;实现单目SLAM空间交互&#xff0c;具有高精度、实时性和稳定性。发布UXR2.0SDK&#xff0c;为构建空间内容提供丰富的开发套件 多模态交互 算法原子化 多种开发工具协同 多生态支持 骁龙XR2…

无swing,高级javaSE毕业之贪吃蛇游戏(含模块构建,多线程监听服务),已录制视频

JavaSE&#xff0c;无框架实现贪吃蛇 B站已发视频&#xff1a;无swing&#xff0c;纯JavaSE贪吃蛇游戏设计构建 文章目录 JavaSE&#xff0c;无框架实现贪吃蛇1.整体思考2.可能的难点思考2.1 如何表示游戏界面2.2 如何渲染游戏界面2.3 如何让游戏动起来2.4 蛇如何移动 3.流程图…

Jetsonnano B01 笔记7:Mediapipe与人脸手势识别

今日继续我的Jetsonnano学习之路&#xff0c;今日学习安装使用的是&#xff1a;MediaPipe 一款开源的多媒体机器学习模型应用框架。可在移动设备、工作站和服务 器上跨平台运行&#xff0c;并支持移动 GPU 加速。 介绍与程序搬运官方&#xff0c;只是自己的学习记录笔记&am…

QT 完成登陆界面跳转到聊天室+完成学生管理系统的查找和删除功能

一、完成登陆界面跳转到聊天室 1> 项目结构 2> 源码 ① .pro ②main #include "mywnd.h" #include"chatCli.h" #include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);MyWnd w;w.show();Form f;QObject::co…

Vue2+Vue3基础入门到实战项目(前接六 副线一)—— 面经 项目

day1 接口文档地址&#xff1a;https://www.apifox.cn/apidoc/project-934563/api-20384515 一、项目功能演示 1.目标 启动准备好的代码&#xff0c;演示移动端面经内容&#xff0c;明确功能模块 2.项目收获 二、项目创建目录初始化 vue-cli 建项目 1.安装脚手架 (已安装…

对Spring核心思想的理解(二)

Spring的第二大核心思想&#xff0c;面向切面编程。 官方定义是&#xff1a;通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续&#xff0c;是软件开发中的一个热点&#xff0c;也是Spring框架中的一个重要内容&#xff0c;是函数式编程的一种衍…

【大数据实训】用Hbase模拟电影搜索引擎(四)

博主介绍&#xff1a;✌全网粉丝6W,csdn特邀作者、博客专家、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于大数据技术领域和毕业项目实战✌ &#x1f345;文末获取项目联系&#x1f345; 《云计算与大数据处理》课程大作业评分表 项目考核内…

python读取监控流通过websocket连接发送到java服务端,服务端推流到前端

python读取逐帧读取监控 import websocket import base64 import cv2 import numpy as npvideoPath "rtmp://ns8.indexforce.com/home/mystream" // 此为公开RTSP流def on_message(ws, message):print(1)def connection_tmp(ws):websocket.enableTrace(True)ws w…

时序分解 | MATLAB实现基于小波分解信号分解分量可视化

时序分解 | MATLAB实现基于小波分解信号分解分量可视化 目录 时序分解 | MATLAB实现基于小波分解信号分解分量可视化效果一览基本介绍程序设计参考资料 效果一览 基本介绍 基于小波分解的分量可视化&#xff0c;MATLAB编程程序&#xff0c;用于将信号分解成不同尺度和频率的子信…

动态库的制作和使用

动态库和静态库的工作原理 配置环境变量 方式1&#xff1a; 坏处&#xff1a;环境变量是临时的 方式2&#xff1a; 1 用户级别的配置&#xff1a; 进入到/home&#xff0c;找到.bashrc&#xff0c;进入 先去找到库的路径 然后再到.bashrc最后一行输入路径 使其生效 2 系统…