虚拟内存的分配brk/sbrk 您所在的位置:网站首页 brk是什么牌子 虚拟内存的分配brk/sbrk

虚拟内存的分配brk/sbrk

2024-02-17 03:13| 来源: 网络整理| 查看: 265

Linux进程级的内存管理      首先,我们可以了解一下一个进程的内核空间: 可以看到一个进程地址空间的主要成分为:

正文:这是整个用户空间的最低地址部分,存放的是指令(也就是程序所编译成的可执行机器码)

初始化数据段:这里存放的是初始化过的全局变量

未初始化数据段:这里存放的是未初始化的全局变量

Heap:堆,这是我们本文重点关注的地方,堆自低地址向高地址增长,后面要讲到的brk相关的系统调用就是从这里分配内存

Stack:这是栈区域,自高地址向低地址增长

命令行参数和环境变量:用户调用的最底层。

  我们都知道,在malloc分配空间时是在Heap上分配的,实质上,Linux维护一个break指针,这个指针指向堆空间的某个地址。从堆起始地址到break之间的地址空间为映射好的,可以供进程访问;而从break往上,是未映射的地址空间,如果访问这段空间则程序会报错。

由上文知道,要增加一个进程实际的可用堆大小,就需要将break指针向高地址移动。Linux通过brk和sbrk系统调用操作break指针。两个系统调用的原型如下:

 

栈:编译器自动生成代码维护 堆:地址是否映射,映射的空间是否被管理. 1.brk/sbrk 内存映射函数

malloc是c中常用的内存操作函数,malloc动态的申请一块指定大小的内存,方便存放数据

c++中的new实际上除了malloc分配内存之外还会调用构造函数初始化数据

而brk/sbrk则是实现malloc的底层函数,其中brk是系统调用。操作起来更为灵活,但很多人往往不容易理解。

int brk(void *addr);   //分配空间,释放空间 void *sbrk(intptr_t increment); //返回空间地址

返回值:    brk()成功返回0,出错返回-1,并且errno被设置为ENOMEM    sbrk()成功返回上一个程序结束点,出错返回-1,并且errno被设置为 ENOMEM

 

 brk()和sbrk()改变程序间断点的位置(break指针)。程序间断点就是程序数据段的结尾。(程序间断点是为初始化数据段的起始位置).通过增加程序间断点进程可以更有效的申请内存

       当addr参数合理、系统有足够的内存并且不超过最大值时brk()函数将数据段结尾设置为addr,即间断点设置为addr       sbrk()将程序数据空间增加increment字节。当increment为0时则返回程序间断点的当前位置。   

什么是程序间断点呢?可以这样理解,进程在内存中被分为代码区,数据区,栈区和堆区。程序间断点指向堆区的起始位置。同时他也是数据段的结尾。Linux进程内存分布,地址从低到高依次是代码段,数据段,堆,栈,堆栈之间是mmap映射的共享内存空间以及共享库,再上是命令行参数,环境变量等,其中栈是从高地址向低地址分配,堆是从低地址向高地址分配。程序间断点就是当前进程映射虚拟地址的终止位置,通过移动这个位置来维护进程的映射的内存.而brk/sbrk的作用就是维护这个位置.

brk改变绝对位置sbrk相对改变位置 >0则增加位置



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有