操作系统:malloc与堆区内存管理

malloc是函数而不是系统调用,他的底层是同调调用brk和mmap这两个系统调用实现功能的,具体选择brk还是mmap要看申请的空间大小以及malloc中的阈值(一般是128kb)

注意申请的空间只有使用才会触发缺页中断映射到物理内存

不理解的话先去学习一下分页和分段这些概念

brk

特点

  • 进行堆指针的偏移
  • 申请的空间会比申请的大
  • 容易产生内存碎片
  • 空间释放后不会返回给操作系统而是给内存池
  • 维持了内存池从而减少了系统调用

mmap

特点

  • 申请的空间大
  • 申请的空间释放后回归操作系统而非内存池
  • 从文件映射区挖一块内存

brk相较于mmap适合用作小空间处理的原因可以从两方面理解

  • brk的原理是移动堆指针,地址连续用着用着会产生大量的内存碎片,性能提升不会太高
  • 减少对操作系统并发性的影响,大空间被挖走当内存池会影响操作系统的整体性能

free释放时是如何知道释放多大空间的

在malloc的前边几个字段会存储申请的空间大小,释放的时候会偏移回去,可以借助指针看看,空间大小一般会比申请的大

cpp 复制代码
#include<iostream>
#include<stdlib.h>
using namespace std;
int main(){
    int *cur=(int*)malloc(32);
    for(int i=0;i<8;i++) cur[i]=i;
    for(int i=-5;i<15;i++){
        cout<<*(cur+i)<<endl;
    }
}

可以看到这里的实际大小是奇数,计算一下,堆的对齐方式是16字节,头部8字节,多申请一位应该是为了避免你申请8字节时出现堆指针和内存重叠的情况,你细品

内存不够用时申请物理内存会发生什么

如果没有空闲的物理内存,那么内核就会开始进行回收内存的工作,回收的方式主要是两种:直接内存回收和后台内存回收。

  • 后台内存回收:在物理内存紧张的时候,会唤醒 kswapd 内核线程来回收内存,这个回收内存的过程异步的,不会阻塞进程的执行。
  • 直接内存回收:如果后台异步回收跟不上进程内存申请的速度,就会开始直接回收,这个回收内存的过程是同步的,会阻塞进程的执行。
  • 如果直接内存回收后,空闲的物理内存仍然无法满足此次物理内存的申请,那么内核就会触发 OOM机制,OOM机制会根据页面置换算法选择一个占用物理内存较高的进程,然后将其杀死,以便释放内存资源,如果物理内存依然不足,OOM会继续杀死占用物理内存较高的进程,直到释放足够的内存位置。

回收对象

  • 文件页,缓存磁盘数据/缓存文件数据等,如果修改过没有提交是脏页需要进行页面置换,否则的话一般认为可以直接释放
  • 匿名页,比如栈、堆数据,这类必须要进行页面置换

所以说当申请的空间大于实际拥有的内存量时需要进行大量的文件IO会变得非常的卡,可以设置回收倾向来适当缓解,一般推荐优先回收文件页

new/delete和malloc/free的关系

相关推荐
怀民民民18 小时前
双通道点光源追踪系统
单片机·嵌入式硬件·开源·操作系统·串口·硬件·frtos
想做后端的小C3 天前
操作系统:SPOOLing(假脱机技术)
操作系统·假脱机技术
小林up3 天前
【MIT-OS6.S081作业5.1】Lab5-lazy page allocation-Eliminate allocation from sbrk()
操作系统·xv6
AthlonxpX863 天前
关于OceanBase tpmC场景与异数OS 元宇宙OLTP场景的异同答疑。
操作系统·oceanbase·架构师·元宇宙·tps·oltp·数据库引擎
fakerth3 天前
【OpenHarmony】Hiview架构
架构·操作系统·openharmony
Trouvaille ~4 天前
【Linux】库制作与原理(二):ELF格式与静态链接原理
linux·运维·c语言·操作系统·动静态库·静态链接·elf文件
小李独爱秋4 天前
Linux操作系统实验报告单(13) 显示进程列表
linux·运维·服务器·操作系统·实验报告单
_OP_CHEN4 天前
【Linux系统编程】(十八)Linux 进程创建与终止进阶:等待机制与程序替换的底层密码
linux·服务器·操作系统·进程·进程等待·进程替换·exec函数族
柏木乃一4 天前
进程(6)进程切换,Linux中的进程组织,Linux进程调度算法
linux·服务器·c++·算法·架构·操作系统