操作系统: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的关系

相关推荐
LUCIAZZZ3 小时前
说一下分布式组件时钟一致性的解决方案
java·网络·分布式·计算机网络·操作系统·springboot·系统设计
IceMan1 天前
进程间通信(一)管道通信
操作系统
罗念笙1 天前
说下你常用的Linux命令?
linux·操作系统
想拿高薪的韭菜2 天前
操作系统高频(六)linux内核
linux·操作系统
LUCIAZZZ2 天前
计算机网络-TCP的重传机制
java·网络·网络协议·tcp/ip·计算机网络·操作系统·springboot
tinker2 天前
Ubuntu 初始安装记录
操作系统
Zevalin爱灰灰3 天前
面试可能会遇到的问题&回答(嵌入式软件开发部分)
stm32·单片机·面试·操作系统·嵌入式·ucos
热爱前端的小张4 天前
第三章 内存管理(下)
操作系统
易保山6 天前
MIT6.S081 - Lab6 Copy-on-Write(写时复制)
linux·操作系统·c
司六米希6 天前
【操作系统】查内存泄漏方法
操作系统