Linux下malloc/free内存碎片问题

C语言内存模型详解 C语言内存模型详解second60  201804151 内存模型在C语言中,内存可分用五个部分:1. BSS段(Block Started by Symbol): 用来存放程序中未初始化的全局变量的内存区域。2. 数据段(data segment): 用来存放程序中已初始化的全局变量的内存区域。3. 代码段(text segment): 用来存放程序执行代码的内存区域。4. 堆(heap):用来... 阅读详情

通过对malloc,free源码的分析,发现在堆上分配内存,很容易造成内存碎片。内存碎片在这里可以从两个方面进行分析,物理地址的内存碎片和线性地址(虚拟地址)的内存碎片。

首先是物理地址的内存碎片,malloc_free_list大小依次为8,16,32....。那么我们请求的大小加上4字节的额外开销,如果和malloc_free_list插槽的大小一致,就不会产生碎片,反之,就会。如请求大小为5,那么加上额外开销大小就为9,第一个插槽无法满足,只有第二个插槽满足,但是第二个插槽分配单位是16,那么就是只有9个字节的大小,也要占用一个16字节的单元,相应的产生了7个字节的内存碎片。对于小数据单元来说,因为每次请求内存,最小是一页,比如对于第一个插槽,就会产生4096/8个单元,但程序不一定会申请这么多小的内存块,相应的这也不能高效的利用物理内存。这里还有个问题,如果内存不断的申请,如连续分配了多个物理页面供一个插槽使用,那么当释放时,程序会把物理内存归还给系统吗?至少在free中,是没有做的,也做不到,它只是简单的把内存单元添加到malloc_free_list插槽中。关于物理页面释放的问题,只有通过内核代码,才能确定物理内存释放的机制,而每个程序虚拟内存是通过vm_area_struct来管理的。

其次是线性地址的内存碎片,对于32位系统来说,用户虚拟地址只有3G,除了程序代码段,数据段,栈...,留给堆的有效线性地址也是有限的。如果频繁的分配小的内存块,他就会占用小的页面,这样当程序释放内存时,就会产生许多小的不连续的线性地址,当程序需要连续大的线性地址时,就会产生麻烦。具体是怎么实现的,等查了内核代码就明白了。

通过以上分析,对于在堆上申请内存,是会产生一定代价的,特别是滥用,后果也是比较严重的。内存碎片是需要关注的问题。

malloc/free背后的虚拟内存真相:从缺页中断到RSS不降 malloc和free是C/C++内存管理的基础接口,但其行为本质由虚拟内存机制决定。理解虚拟地址空间、缺页中断、页表映射与物理页分配的协同关系,是掌握内存真实开销的关键。glibc的malloc通过brk和mmap双路径分配内存,小块复用堆区(不触发内核释放),大块走匿名映射(free即munmap)。这导致free后RSS不降、valgrind漏检、OOM突袭等典型问题。深入proc文件系统(maps/smaps)、结合overcommit策略与MMU页管理,才能实现高可靠内存工程实践。 阅读详情

相关推荐

malloc和free底层实现原理

前言 从操作系统角度来看,进程分配内存有2种方式,分别由2个系统调用完成:brk和mmap(不考虑共享内存)。 brk是将数据段(.data)的最高地址指针_edata往高地址推 mmap是在进程的虚拟地址空间中(堆和栈中间,称为文件映射区域的地方)找一块空闲的虚拟内存。 这两种方式分配的都是虚拟内存,没有分配物理内存。在第一次访问已分配的虚拟地址空间的时候,发生缺页中断,操作系统负责分配物理内...

qq_35429629的博客 2776

Linux内存管理:malloc/free实现原理与优化

内存管理是操作系统的核心功能,其中动态内存分配通过malloc/free接口实现。这些函数底层依赖brk/sbrk系统调用与内核交互,但直接系统调用开销大,因此现代实现采用内存池策略。内存控制块(MCB)记录分配信息,通过显式或隐式空闲链表管理。分配算法如首次适应、最佳适应各有优劣,而分离空闲链表等高级技术能提升性能。实际应用中,tcmalloc等优化方案通过线程本地缓存减少锁竞争。理解这些机制对开发高性能应用、解决内存泄漏和碎片问题至关重要,特别是在多线程和实时系统中。

weixin_36122351的博客 594

(超详细)Scala环境搭建(scala-2.12.15、IDEA2021.1.3)

Scala环境搭建(scala-2.12.15、IDEA2021.1.3) JunLeon——go big or go home 目录 Scala环境搭建(scala-2.12.15、IDEA2021.1.3) 一、Scala概述 1、什么是Scala? 2、Scala发展史 3、Scala与Java的关系 二、Scala环境搭建 1、环境准备 2、Scala安装与配置环境变量 3、验证Scala 三、编写第一个Scala程序 1、使用IDEA创建maven工程 2、.

JunLeon的博客 3万+

频繁分配释放内存的性能问题

  在调优程序的过程中发现对于分辨率大小不同的两个图库,程序总的运行性能数据(如FPGA kernel利用率及每张图处理的latency)差别很大,使用/usr/bin/time  –v分析程序发现测试两个图库时,报的minor falut(次缺页错误)不是一个数量级别的。  linux系统下面缺页异常主要分为四种情况。minor falut属于请求调页的一种。当malloc函数调用时,并未实际分...

weijitao的博客 5322

Mac本地大模型实战指南:Ollama+Metal+Apple Silicon深度优化

大语言模型(LLM)本地化部署正成为开发者关键技术能力,其核心在于推理效率、硬件适配与成本控制。Apple Silicon凭借统一内存架构(UMA)和Neural Engine,为本地LLM运行提供了独特优势;Metal加速则显著提升GPU计算吞吐,使Gemma 4、Qwen 3.5等模型在M系列Mac上实现低延迟、高精度、离线可用的工程落地。相比云端API,本地方案规避了token计费、网络依赖与数据外泄风险,特别适用于企业文档处理、实时语音分析、私有知识库检索等强隐私、低时延场景。本文聚焦Mac平台,系

weixin_33443333的博客 352

Fedproto:原型聚合的联邦学习框架

文中说明,联邦学习通过计算传递梯度聚合模型时,客户端之间的异构性通常会阻碍模型优化收敛和泛化性能。故本文提出新的FedProto框架,将梯度替换成为原型,通过计算、聚合从不同客户端收集到的本地原型,然后将全局原型发送回所有客户端,以规范本地模型的训练。对每个客户机进行局部训练的目的是最小化对本地数据的分类损失,同时保持生成的本地原型足够接近相应的全局原型(损失函数最小+正则)。什么是原型?文中提到:“

weixin_47754029的博客 2650

在频繁调用的底层函数中使用malloc的影响分析

近来,测试中发现一个问题,ipcam会自动重启。经过定位,是增加了一个外部i2c timer作为看门狗引起的。 看了ex-wdt keep alive的code后发现,调用了一个i2c_WriteBytes()函数,这个Func中调用了两次malloc申请内存,并且,对malloc分配的 指针未作NULL的检查。我认为问题就出在这里,原因是这样: 1、虽然在这个Func中,malloc与fr

Power of technology will free your body and spirit 3537

Frenet坐标系下动态街道场景的最优轨迹生成

本文详细解读了Lattice Planner

BigDavid123的博客 2393

C语言中频繁的malloc和free导致的free()错误

背景:网络数据处理的程序,2Gbps的流量,每个数据包都有数次malloc和free操作 经过:使用tcpreplay回放数据包进行测试,同一批数据反复回放,在15分钟左右会出现free()的错误,错误出现时间不固定,最长坚持了45分钟,由于要求程序至少要坚持1小时,所以这个错误不能接受 解决过程:仔细检查所有free的地方,确认没有野指针,也没有double free,原因无法确定 解决方

oMADAO123的博客 5664

基于PCA的故障诊断方法(matlab)

1. PCA原理分析 PCA的原理主要是将原始数据进行降维。其具体工作原理参照:CodingLabs - PCA的数学原理 2. 数据预处理 训练数据集(只有正样本)为维数据,即有n个采样值,每个采样值有m个特征。 2.1 数据归一化 将数据X针对每个特征归一化为均值为0,均方根为1的数据。 其中: 3. PCA降维 3.1 首先求取协方差矩阵 协方差矩阵的公式为: 计算出来的协方差矩阵为特征m*m维矩阵。 3.2 求取特征值和特征向量 求取协方差矩阵R的特征值.

tangxianyu的博客 1万+

Dify 第 19 篇 手把手教你开发 Dify 插件:从零实现一个时间工具

本文介绍了Dify平台的插件开发机制和流程。Dify支持多种插件类型,包括模型、工具、数据源等,可通过CLI工具快速开发插件。文章详细讲解了如何安装Dify CLI工具,并演示了从零开发一个获取系统时间插件的完整过程,包括项目初始化、文件解读和打包部署。通过该教程,开发者可以快速掌握Dify插件开发的核心要点,实现自定义功能扩展。

甘蓝的专栏 2451

不显示删除回复显示所有回复显示星级回复显示得分回复 [推荐] [百度分享]频繁分配释放内存导致的性能问题的分析

现象1 压力测试过程中,发现被测对象性能不够理想,具体表现为: 进程的系统态CPU消耗20,用户态CPU消耗10,系统idle大约70 2 用ps -o majflt,minflt -C program命令查看,发现majflt每秒增量为0,而minflt每秒增量大于10000。初步分析majflt代表major fault,中文名叫大错误,minflt代表minor fault,中文名叫小错误。

newish21的专栏 712

基于STM32、HAL库的ADE7880ACPZ-RL电能计量芯片驱动程序设计

@retval 状态 (ADE7880_OK或ADE7880_ERROR)* @retval 状态 (ADE7880_OK或ADE7880_ERROR)* @retval 状态 (ADE7880_OK或ADE7880_ERROR)* @retval 状态 (ADE7880_OK或ADE7880_ERROR)* @retval 状态 (ADE7880_OK或ADE7880_ERROR)PA6 (MISO) <--> SDO (SPI数据输出)PB0 (CS) <--> /CS (片选,低有效)

corlin6688的博客 668

Linux基础组件之内存池的实现

设计一个内存池,可以有效的避免内存碎片和避免频繁的内存创建‘释放。程序通常能管理的内存主要是堆和共享内存(mmap)。应用层所谓的内存管理,主要是对堆上的内存池进行管理。内存管理方式,使用比较多的是以2n2^n2n堆叠内存池以及大小块方式管理。nginx就是使用的大小块方式管理内存;

Lion_Long的博客 2110

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Linux内存布局详解

从堆段分配出nmemb*size字节的内存,即分配一块可容纳nmemb个元素、每个元素大小为size字节的数组的内存,将这块内存的初始化为0,并返回这块内存的起始地址。这个128KB可通过。:重新调整ptr所指向的已分配的内存大小为size字节,不会改变原来的内存的内容,也不会初始化新增的内存。从内存映射区申请内存,且释放时也可直接归还内存映射区的这块内存给内核,但是内核需要建立一系列复杂的数据结构来完成内存映射区的内存申请。:从堆段分配出size字节的内存,不会初始化这块内存,返回这块内存的起始地址。

llb_1203的博客 1900

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

在glibc中是如何分配一块堆内存的(malloc)

为什么在linux上读取到空指针会导致程序crash linux会为进程的用户空间的0x0的虚拟地址映射到一个用户没有权限访问的页中,内核保证没有其它页映射到这个区域。 编译器会将空指针编译成指向0x0的虚拟地址,程序可以去读取地址 这时候会按照正常流程,读取地址就会触发缺页中断,缺页异常程序会被调用,然后去读取一块没有访问权限的页,缺页异常程序发现没有访问权限,内核会发送SIGSEGV 信号给进程,该信号默认是让进程自杀。 ...

weixin_42146864的博客 498

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

free()后内存不释放问题 - 内存缓冲池技术(转)

起因 下面这段代码执行后,内存有增无减,增加了200M,iOS平台200M不能接受了 // STL 集合类 void test1() { list<int> mList; for (int i=0; i<1000000; i++) { mList.push_back(i); } mList.clea...

weixin_30819085的博客 2219

内存池的实现

如果下次再次分配内存时,假如大块内存分配区中的一小块内存为4096B,如果需要8KB,此时虽然总剩余内存大小大于8KB,但是实际可分配的连续内存却小于8KB,这就是内存碎片。代码的逻辑是,采用pool进行逻辑层的管理,管理两个内存链表,一个是小块内存链表,一个是大块内存链表。/*将内存池起始地址强转为node_s*/内存碎片:内存实际没有占满,但由于大量碎片化的内存导致无法分配内存,导致的内存耗尽的问题。

m0_71530792的博客 321

malloc/free 的内核足迹:从虚拟内存到系统调用的底层真相

虚拟内存是现代操作系统的核心机制,它通过MMU地址翻译、缺页异常处理和页帧复用,为进程提供隔离、连续且按需分配的地址空间。malloc/free 并非简单的内存申请与释放,而是用户态分配器(如ptmalloc2)与内核内存管理(伙伴系统、mmap/brk系统调用)协同作用的结果。其技术价值在于揭示‘分配即映射、释放未必归还’这一关键原理——小块内存常走brk路径,free后仅链入bin,RSS不降;大块则触发mmap,free时立即munmap并回收物理页。典型应用场景包括嵌入式内存泄漏排查、高频服务RSS

weixin_29217235的博客 252

C 语言学习笔记Day16 | 内存管理、调试技巧与库文件全梳理

malloc 与 free 必须成对出现:只申请不释放会造成内存泄漏;重复 free 会触发程序崩溃。栈区空间不能用 free 释放:free 只能释放堆区内存,释放栈区变量会直接报错。字符串函数越界风险getsstrcpy等无长度限制的函数存在缓冲区溢出风险,优先使用带长度限制的安全函数。野指针访问:free 释放后的指针、未初始化的指针,都不能直接访问,否则会触发段错误。

2401_89475491的博客 564

Linux 下 C 语言内存管理、程序调试与库机制综合知识点梳理

本文梳理 Linux 环境 C 语言开发核心知识,讲解堆内存 malloc 与 free 的用法、内存泄漏与碎片成因及优化手段。区分语法、逻辑、段错误三类程序故障,介绍 printf 排查、GDB 断点调试、core 文件定位崩溃、valgrind 检测内存泄漏等调试方案。同时讲解 Ubuntu 虚拟机联网、更换国内软件源步骤,对比静态库与动态库加载特性、优缺点,给出 ldd 查看动态依赖的实操命令,覆盖 Linux C 开发调试与环境配置实用内容。

2601_96618230的博客 155

deer-flow:运行时内存行为观测器原理与实战

内存管理是程序稳定性的底层基石,其核心在于分配、访问、释放的全生命周期控制。传统工具如Valgrind或AddressSanitizer依赖编译插桩或运行时GC日志,难以覆盖跨语言、跨进程及系统级内存操作。deer-flow通过LD_PRELOAD/DLL注入机制,在操作系统原语层(malloc/mmap/VirtualAlloc)实现无侵入钩子,实时捕获内存申请、释放、越界访问等行为,尤其擅长诊断0xc0000005崩溃、use-after-free和地址空间碎片化等典型问题。它不替代调试器,而是作为‘内

weixin_28839601的博客 152

malloc 是如何分配内存的?

大家好,我是小林。 很早之前写了一篇图解虚拟内存的文章:真棒!20 张图揭开内存管理的迷雾,瞬间豁然开朗 最近想多写一些内存管理的文章,这次我们就以 malloc 动态内存分配为切入点,我在文中也做了小实验: malloc 是如何分配内存的? malloc 分配的是物理内存吗? malloc(1) 会分配多大的内存? free 释放内存,会归还给操作系统吗? free() 函数只传入一个内存地址,为什么能知道要释放多大的内存? 发车! Linux 进程的内存分布长什么样? 在 Linux 操作系统中,

小林coding 1万+

linux malloc free 内存碎片_嵌入式裸机编程中使用malloc、free会怎样?

在嵌入式裸机编程中,作为一名初级的CODER。经常要与CPU、内存等打交道。CPU作为系统的动力源,其重要程度不言而喻。但是,在裸机编程中,对内存的管理也不容忽视。如果稍微不注意,轻则,可能造成内存泄漏,重则造成内存访问异常。导致系统死机。嵌入式产品,对稳定性要求及其严格。动不动就死机,那可就麻烦大了。以下,是我本人对嵌入式系统裸机编程的内存管理的一些简介。1、尽量不使用库自带的mall...

weixin_39625747的博客 363
上一篇: Linux下malloc/free详解
下一篇: 守护进程,xinetd使用
livedrm
博客等级 码龄17年 11粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值