(转)Linux进程与它的堆栈空间
一、概述
堆栈是一个用户空间的内存区域,进程使用
堆栈作为
临时存储。
堆栈中存放的是函数中的局部变量,在函数的生命周期中可将变量压入堆栈,编译器需确保堆栈指针在函数退出前恢复到初始位置,即是说,内存是自动分配和释放的。
C/C++把存储在堆栈中的局部变量当作automatic存储,并使用auto关键字,这是局部变量的默认存储方式,所以现在没人用auto关键词。
与动态存储相对应的
静态存储,即用static定义的局部变量,不用堆栈来存储,而是使用
数据段。
堆栈的基地址位于用户空间的最高虚拟地址附近,并从那里向下延伸。
一个进程开始,堆栈的最大值就不能改变,如果占用的空间超过了堆栈大小,就导致堆栈溢出。
二、进程的内存组织形式
进程被分为三个区域:
文本、
数据和
堆栈 1) 文本区域
文本区域也叫做
代码段,由程序确定,包括代码(指令)和只读数据。该区域通常被标记为只读,任何对其写入的操作会导致段错误。
2) 数据区域
数据区域也叫做
数据段,包括已初始化和未初始化的数据,静态变量存储在这个区域中。
3) 堆栈区域
堆栈区域也叫
堆栈段,它用于给局部变量动态分配空间,同样函数传递参数和函数返回值也要用到堆栈。
堆栈也可向下增长(向内存低地址)也可以向上增长,依赖于具体的实现。通常是向下增长,而SP(堆栈指针)也是指向堆栈的最后地址。
4) 内存的分配区域
通常
堆栈位于最高虚拟地址附近,而数据段位于
堆栈段之后,最后是
代码段。
三、堆栈着色
当两个线程或进程使用相同的堆栈虚拟地址时,它们会争夺同一个cache行,导致竞争和降级行为。
堆栈着色的技术使每一个进程的基址都不相同,通过随机分配堆栈基址,多个进程会使用不同的cache行来避免。
四、常驻内存和锁定内存
常驻内存专指存储在RAM中的内存部分,不包括存储在交换区和未存储的进程的内存。
锁定内存是常驻内存的子集,它指被进程明确地锁定到RAM的虚拟内存中,不能用于交换,并一直常驻于RAM中。