• Linux内核有什么之内存管理子系统有什么第三回 —— 小内存分配(1)


    接前一篇文章:Linux内核有什么之内存管理子系统有什么第二回 —— 单刀直入

    本文内容参考:

    内存分配不再神秘:深入剖析malloc函数实现原理与机制

    系统调用与内存管理(sbrk、brk、mmap、munmap)

    特此致谢!

    二、小内存分配 —— brk与sbrk

    上回讲到通过malloc()申请一个堆内的空间,底层要么执行brk(小内存分配),要么执行mmap(大内存分配)。二者之间的界限是MMAP_THRESHOLD(默认128KB)。小于等于MMAP_THRESHOLD的使用brk,大于MMAP_THRESHOLD的使用mmap。

    先来看小内存分配。上一回中man malloc得到的说明中实际上提到了两个相关的系统调用:brk与sbrk。依旧在Linux终端下通过man brk查看其说明,如下所示:

    两个系统调用的说明如下:

    名称

    brk,sbrk

    原型

    #include

    int brk(void *addr);
    void *sbrk(intptr_t increment);

    说明

    brk()和sbrk()改变程序间断点的位置,程序间断点就是进程数据段的结尾。(例如,程序间断点是未初始化数据段的结束之后的首个位置)。增加程序间断点具有为进程分配内存的效果;减少程序间断点则释放内存。

    当addr参数合理、系统有足够的内存并且不超过最大值时,brk()函数将数据段结尾设置为addr,即间断点设置为addr(请参阅setrlimit(2))。

    sbrk()将程序数据空间增加increment字节。当increment为0时则是返回程序间断点的当前位置。

    brk()将break指针直接设置为某个地址,而sbrk()将break指针从当前位置移动increment所指定的增量。

    返回值

    brk()成功时返回0,失败返回-1并且设置errno值为ENOMEM。

    sbrk()成功时返回之前的程序间断点地址。如果间断点值增加,那么这个指针(指的是返回的之前的间断点地址)是指向分配的新的内存的首地址。如果出错失败,就返回一个(void *) -1
    并设置errno全局变量的值为ENOMEM。

    避免使用brk()和sbrk():malloc(3)内存分配包是一种可移植且舒适的内存分配方式。

    总结

    brk()和sbrk()都用来改变 “program break”(程序间断点)的位置,改变数据段长度(Change data segment size),实现虚拟内存到物理内存的映射。

    • brk()直接修改有效访问范围的末尾地址实现分配与回收。
    • sbrk()函数当参数increment为正值时,程序间断点位置向后移动increment字节,同时返回移动之前的位置,相当于分配内存;当increment为负值时,位置向前移动increment字节,相当与于释放内存,其返回值没有实际意义;当increment为0时,不移动位置只返回当前位置。参数increment的符号决定了是分配还是回收内存。

    下一回开始结合代码,对于brk()和sbrk()进行详解。

  • 相关阅读:
    文件的随机读写函数:ftell & rewind
    FastAPI学习-24.自定义异常处理器 exception_handler
    TFT-LCD屏幕显示图片
    CMake教程——Leeds_Garden
    Redis 和 Memcache 的区别
    机器学习(一):概述
    永州出入境检验实验室建设那些事
    Redis之key命令
    C习题002:澡堂洗澡
    JMeter压测如何分配业务比例?
  • 原文地址:https://blog.csdn.net/phmatthaus/article/details/134300149