linux 进程数据段与堆栈空间的关系

系统进程内部的内存布局是怎样的呢?数据段,程序段,堆空间是如何分配的?

先从进程的数据段开始,就像堆栈段能够根虎需要自动增长一样,数据段也包含了一个对象,用于完成这样工作,这就是堆(heap),如下图显示。

堆区域用于动态分配的存储,也就是通过malloc(内存分配)函数获得的内存,并通过指针访问。堆中的多有东西都是匿名的——不能按名字直接访问,只能通过指针间接访问。从堆中获取内存的唯一方法就是:通过调用malloc(以及同类的calloc、realloc等)库函数。

calloc函数与malloc函数类似,但是它在返回指针之前,先把分配好的内存内容都清空为零(个人理解是相当于进行了memset)。不要以为calloc函数中的c跟C语言编程有关——它的意思是“分配清零后的内存”。

realloc函数改变一个指针所指向的内存块大小,既可以扩大,也可以把内存缩小,它经常吧内存拷贝到别的地方,然后将指向的新地址的指针返回给你,这在动态增长表的大小时很有用。

堆内存的回收不必与它的分配顺序一致(它甚至可以不回收),所以无序的malloc/free最终会产生碎片。堆对它的每一块分区都要密切留心,哪些是已经分配了的,哪些是尚未分配的。其中一种策略就是建立一个可用块(“自由存储区”)的链表,每块由malloc分配的内存块,在自己的前面都标明自己的大小。有些人用arena这个术语描述由内存分配器管理的内存块集合(在SumOS中,就是从当前break位置到数据段结尾之间的区域)。

被分配的内存总是经过对齐的,以适合机器上最大尺寸的原子访问,一个malloc请求申请的内存大小,为方便起见一般被圆整为2的乘方。回收的内存可供重新使用,但并没有(方便)办法把它,从你当前的进程移出并交还给操作系统。

堆的末端由一个为break(如果你对内存的引用超过了break的位置,你的程序就会报错)的指针来标识。当堆管理器需要更多的内存时,它可以通过系统调用brk和sbrk来移动break指针。一般情况下,不必有自己显式地调用brk,如果分配的内存容量很大,brk最终会被自动调用。用于管理内存的调用是:

malloc和free——从堆中获得内存,以及把内存返回给堆。

brk和sbrk——调整数据段的大小至一个绝对值(通过某个增量)。

警告:你的程序可能无法同时调用malloc()和brk()。如果你使用malloc,malloc希望当前你调用brk和sbrk时,它具有唯一控制权。由于sbrk向进城提供了唯一的方法,将数据段内存返回给系统内核,所以如果使用了malloc,就有效地防止进程的数据段缩小的可能性。想要获得以后能返回给系统内核的内存,就可以使用mmap系统调用来映射/dev/zero文件。需要返回这种内存时,可以使用munmap系统调用。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值