linux进程的堆栈空间_代码段(指令,只读)、数据段(静态变量,全局变量)、堆栈段(局部变量)、栈【转】

简介:

转自:http://blog.csdn.net/gongweijiao/article/details/8207333

原文参见:http://blog.163.com/xychenbaihu@yeah/blog/static/132229655201215115845553/ 

 

一)概述

  .堆栈是一个用户空间的内存区域,进程使用堆栈作为临时存储

 

  .堆栈中存放的是函数中的局部变量,在函数的生命周期中可以将变量压入堆栈,编译器需要确保堆栈指针在函数退出前恢复到初始位置,也就是说,内存是自动分配和释放的,C/C++存储在堆栈中的局部变量当作automatic存储,并使用auto关键字,这是局部变量的默认存储方式,所以现在没有人用auto关键词.

 

  .与动态存储(auto)相对映的静态存储(static),也就是用static定义的局部变量,它不用堆栈来存储,而是使用数据段来存储(也就是说它的生命周期在整个程序运行期间)。

 

  .堆栈的基地址位于用户空间的最高虚拟地址附近,并从那里向下延伸。

  .一个进程开始时,堆栈的最大值就不能改变,如果占用的空间超过了堆栈大小,那么就会导致堆栈溢出。

二)进程的内存组织形式

  进程被分为三个区域:文本数据堆栈

  1)文本区域:

   文本区域也叫做代码段,是由程序确定的,

它包括代码(指令)和只读数据,该区域通常被标记为只读,任何对其写入的操作会导致段错误.

  2)数据区域(静态内存分配(static)):

  数据区域也叫做数据段,

它包括已初始化和未初始化的数据,静态变量存储在这个区域中,它的大小可以用系统调用brk(2)来改变。

详细了解数据区域:

分成初始化为非零的数据区BSS(Heap)三个区域。

初始化非零数据区域一般存放静态非零数据和全局的非零数据,属于静态内存分配(全局变量,static修饰的变量);

BSS(Block Started by Symbol)区域(都初始化为0了)一般存放未初始化的全局数据(默认值为0)和未初始化的静态数据(默认值为0),属于静态内存分配(全局变量、static修饰的变量);

堆区域一般存放运行时动态分配的内存空间,其大小不固定,可动态扩张或缩减。当调用malloc等函数分配内存时,新分配的内存被动态添加到堆上;当调用free等函数释放内存时,被释放内存从堆中被剔除。

代码段和数据段之间有明确的分隔,

但是数据段和堆栈段之间没有,而且栈是向下增长,堆是向上增长的,因此理论上堆和栈会“增长到一起”,操作系统的内存管理功能需要防止这样的错误发生。

  3)堆栈区域(动态内存分配auto,默认,所以不用关键字auto):

  堆栈区域也叫堆栈段,

它用于给局部变量动态分配空间,同样函数传递参数和函数返回值也要用到堆栈.

   堆栈也可向下增长(向内存低地址)也可以向上增长,这依赖于具体的实现,

通常都是向下增长的,而SP(堆栈指针)也是指向堆栈的最后地址.

  4)内存的分配区域:

   根据前面所述,堆栈是位于最高虚拟地址附近,而数据段则位于堆栈段之后,最后是代码段。

也就是:

低地址 代码段 或 高地址 堆栈段

数据段 数据段

高地址 堆栈段 低地址 代码段

三)堆栈着色

  当两个线程或进程使用相同的堆栈虚拟地址时,它们会争夺同一个cache行,导致竞争和降级行为.

  堆栈着色的技术使每一个进程的基址都不相同,通过随机分配堆栈基址,多个进程会使用不同的cache行来避免.

四)堆栈的限制

  堆栈空间的最大值是由setrlimit系统调用确定的,也可以通过bash内建的ulimit命令来设定和查看.

  例如:

  查看当前可使用的最大堆栈(以KB为单位)

  ulimit -s

  8192 //栈的大小默认是8M

  设定为最大的使用堆栈为15KB

  ulimit -s 15

  此时执行ls将会得到一个段错误.

  ls -l /etc/

  total 1040

  Segmentation fault

  通过用strace跟踪ls命令,将发现有如下的系统调用

  getrlimit(RLIMIT_STACK, {rlim_cur=15*1024, rlim_max=15*1024}) = 0

  说明当前可用的堆栈空间,已经不足以运行strace命令了.

五)常驻内存和锁定内存

  常驻内存专指存储在RAM中的内存部分,不包括存储在交换区和未存储的进程的内存.

  锁定内存是常驻内存的子集,它指被进程明确地锁定到RAM的虚拟内存中,不能用于交换,并一直常驻于RAM中.










本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sky-heaven/p/5691884.html,如需转载请自行联系原作者



相关文章
|
4天前
|
缓存 监控 Linux
linux进程管理万字详解!!!
本文档介绍了Linux系统中进程管理、系统负载监控、内存监控和磁盘监控的基本概念和常用命令。主要内容包括: 1. **进程管理**: - **进程介绍**:程序与进程的关系、进程的生命周期、查看进程号和父进程号的方法。 - **进程监控命令**:`ps`、`pstree`、`pidof`、`top`、`htop`、`lsof`等命令的使用方法和案例。 - **进程管理命令**:控制信号、`kill`、`pkill`、`killall`、前台和后台运行、`screen`、`nohup`等命令的使用方法和案例。
26 4
linux进程管理万字详解!!!
|
3天前
|
算法 Linux 定位技术
Linux内核中的进程调度算法解析####
【10月更文挑战第29天】 本文深入剖析了Linux操作系统的心脏——内核中至关重要的组成部分之一,即进程调度机制。不同于传统的摘要概述,我们将通过一段引人入胜的故事线来揭开进程调度算法的神秘面纱,展现其背后的精妙设计与复杂逻辑,让读者仿佛跟随一位虚拟的“进程侦探”,一步步探索Linux如何高效、公平地管理众多进程,确保系统资源的最优分配与利用。 ####
24 4
|
4天前
|
缓存 负载均衡 算法
Linux内核中的进程调度算法解析####
本文深入探讨了Linux操作系统核心组件之一——进程调度器,着重分析了其采用的CFS(完全公平调度器)算法。不同于传统摘要对研究背景、方法、结果和结论的概述,本文摘要将直接揭示CFS算法的核心优势及其在现代多核处理器环境下如何实现高效、公平的资源分配,同时简要提及该算法如何优化系统响应时间和吞吐量,为读者快速构建对Linux进程调度机制的认知框架。 ####
|
6天前
|
消息中间件 存储 Linux
|
12天前
|
运维 Linux
Linux查找占用的端口,并杀死进程的简单方法
通过上述步骤和命令,您能够迅速识别并根据实际情况管理Linux系统中占用特定端口的进程。为了获得更全面的服务器管理技巧和解决方案,提供了丰富的资源和专业服务,是您提升运维技能的理想选择。
12 1
|
15天前
|
运维 安全 Linux
Linux中传输文件文件夹的10个scp命令
【10月更文挑战第18天】本文详细介绍了10种利用scp命令在Linux系统中进行文件传输的方法,涵盖基础文件传输、使用密钥认证、复制整个目录、从远程主机复制文件、同时传输多个文件和目录、保持文件权限、跨多台远程主机传输、指定端口及显示传输进度等场景,旨在帮助用户在不同情况下高效安全地完成文件传输任务。
111 5
|
15天前
|
Linux
Linux系统之expr命令的基本使用
【10月更文挑战第18天】Linux系统之expr命令的基本使用
51 4
|
2天前
|
缓存 监控 Linux
|
5天前
|
Linux Shell 数据安全/隐私保护