这篇文章主要记录一下c程序运行时内存空间如何使用。(摘抄自网络)

在一个多任务操作系统中的每个进程都运行在它自己的内存“沙箱”中。这个沙箱是一个虚拟地址空间(virtual address space),在 32 位系统中它总共有 4GB 的内存地址空间,包含内核空间和用户空间:

这些虚拟地址是通过内核页表(page table)映射到物理地址的,并由操作系统内核维护。在典型的Linux 中,内核/用户空间的划分比例为1:3。但是,这并不意味着内核就使用了1G物理内存,它只使用了很少一部分可用的地址空间映射到其所需要的物理内存。内核空间的页表被标记,因此,如果一个用户模式的程序尝试去访问它,将触发一个页面故障错误。

在 Linux 中,内核空间是始终存在的,并且在所有进程中都映射相同的物理内存。内核代码和数据总是可寻址的,准备随时去处理中断或者系统调用。相比之下,用户模式中的地址空间,在每次进程切换时都会发生变化:

一个 Linux 进程的标准段布局如下:

  1. 在进程地址空间中最高的段是栈,存储函数参数和本地变量。调用一个方法或者函数将推送一个新的栈帧stack frame到这个栈。当函数返回时这个栈帧被删除。进程中的每个线程都有它自己的栈。如果向栈中压入过多数据,可能会导致栈空间被耗尽,这将触发一个页面故障,系统会调用相关函数来

    检查栈的增长是否正常。如果栈的大小低于 RLIMIT_STACK 的值(一般是 8MB 大小),那么这是一个正常的栈增长,否则可能是发生了未知问题。这是一个栈大小按需调节的常见机制。但是,栈的大小达到了上述限制,将会发生一个栈溢出,并且,程序将会收到一个段故障Segmentation Fault错误。当映射的栈区为满足需要而扩展后,在栈缩小时,映射区域并不会收缩。访问任何未映射的内存区域都是非法的,并将触发一个页面故障,导致段故障。但

    动态栈增长是唯一例外的情况,当它去访问一个未映射的内存区域是允许的。

  2. 在栈的下面,有内存映射段。在这里,内核将文件内容直接映射到内存。任何应用程序都可以通过 Linux 的 mmap() 系统调用来请求一个映射,内存映射是实现文件 I/O 的高效的方式。因此,它经常被用于加载动态库。有时候,也被用于去创建一个匿名内存映射,这种映射经常被用做程序数据的替代。在 Linux 中,如果你通过 malloc() 去请求一个大的内存块,C 库将会创建这样一个匿名映射而不是使用堆内存。这里所谓的“大”表示是超过了MMAP_THRESHOLD 设置的字节数,它的缺省值是 128 kB,可以通过mallopt()去调整这个设置值。
  3. 内存映射段下面是堆,堆提供运行时内存分配,它分配的数据生存期要长于分配它的函数。大多数编程语言都为程序提供了堆管理支持,在 C 中,堆分配的接口是 malloc() 一族。

    如果在堆中有足够的空间可以满足内存请求,它可以由编程语言运行时来处理内存分配请求,而无需内核参与。否则将通过 brk() 系统调用来扩大堆以满足内存请求所需的大小。堆管理比较复杂,在面对我们程序的混乱分配模式时,它通过复杂的算法,努力在速度和内存使用效率之间取得一种平衡。堆也会出现碎片化

  4. 堆下面是BSS段,在 C 中,BSS 保存未初始化的全局变量、静态变量的内容,它的值在源代码中并没有被程序员设置。
  5. 接下来是数据段,用于保存在源代码中已初始化的全局变量、静态变量的内容。这个内存区域是非匿名的。它映射了程序的二进值镜像上的一部分,即在源代码中给定初始化值的全局变量、静态变量内容。

  6. 最后一部分就是代码段,通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

最后关于变量保存位置:

1、经过初始化的全局变量和静态变量保存在数据段中。
2、未经初始化的全局变量和静态变量保存在BSS段,或者初始化为0的全局变量和静态变量。
3、函数内部声明的局部变量保存在堆栈段中。
4、const修饰的全局变量保存在文本段中,const修饰的局部变量保存在堆栈段中。
5、字符串常量保存在文本段中。

c程序内存模型的更多相关文章

  1. JVM内存模型分析(一个程序运行的例子)

    (.class字节码)类加载到内存之后,内存模型:(ps:.class文件可以通过javap 指令反编译成一个可读文件) 1.java栈,本地方法栈,程序计数器(每个线程私有) 看如下程序: 以该程序 ...

  2. 一个试图了解JVM内存模型的两年经验的初级程序员,透彻!

    所有的编程语言中都有内存模型这个概念,区别于微架构的内存模型,高级语言的内存模型包括了编译器和微架构两部分.我试图了解了Java.C#和Go语言的内存模型,发现内容基本大同小异,只是这些语言在具体实现 ...

  3. 内存模型 Memory model 内存分布及程序运行中(BSS段、数据段、代码段、堆栈

    C语言中内存分布及程序运行中(BSS段.数据段.代码段.堆栈) - 秦宝艳的个人页面 - 开源中国 https://my.oschina.net/pollybl1255/blog/140323 Mem ...

  4. 程序猿的日常——JVM内存模型与垃圾回收

    Java开发有个很基础的问题,虽然我们平时接触的不多,但是了解它却成为Java开发的必备基础--这就是JVM.在C++中我们需要手动申请内存然后释放内存,否则就会出现对象已经不再使用内存却仍被占用的情 ...

  5. Java内存模型深度解析:总结--转

    原文地址:http://www.codeceo.com/article/java-memory-7.html 处理器内存模型 顺序一致性内存模型是一个理论参考模型,JMM和处理器内存模型在设计时通常会 ...

  6. JVM学习(3)——总结Java内存模型

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: 为什么学习Java的内存模式 缓存一致性问题 什么是内存模型 JMM(Java Memory Model)简 ...

  7. 浅析java内存模型--JMM(Java Memory Model)

    在并发编程中,多个线程之间采取什么机制进行通信(信息交换),什么机制进行数据的同步? 在Java语言中,采用的是共享内存模型来实现多线程之间的信息交换和数据同步的. 线程之间通过共享程序公共的状态,通 ...

  8. JMM(java内存模型)

    What is a memory model, anyway? In multiprocessorsystems, processors generally have one or more laye ...

  9. 《深入理解Java内存模型》读书总结

    概要 文章是<深入理解Java内容模型>读书笔记,该书总共包括了3部分的知识. 第1部分,基本概念 包括"并发.同步.主内存.本地内存.重排序.内存屏障.happens befo ...

随机推荐

  1. 加载hive-jdbc driver时报错:java.lang.NoClassDefFoundError: org/apache/hadoop/conf/Configuration

    这是因为缺少一个hadoop-common包,引入即可: <dependency> <groupId>org.apache.hadoop</groupId> < ...

  2. 洛谷P5119 Convent 题解

    题目 很好想的一道二分题,首先,二分一定满足单调性,而题目中非常明显的就是用的车越多,所用时间越少,所以可以枚举时间,判断是否可以比\(m\)少. 然后在二分时,更是要注意下标的一些问题,也要注意车和 ...

  3. mysql varcahr转int类型

    cast(yysid as SIGNED INTEGER)

  4. UVA11825 黑客的攻击 Hackers' Crackdown 状压DP,二进制,子集枚举

    题目链接Click Here [题目描述] 假如你是一个黑客,侵入了一个有着\(n\)台计算机(编号为\(1.2.3....n\))的网络.一共有\(n\)种服务,每台计算机都运行着所有服务.对于每台 ...

  5. metasploit与Cobaltstrike互相派生shell

    msf 派生 shell 给 Cobalt strike(前提有一个meterpreter) msf exploit(handler) > use exploit/windows/local/p ...

  6. js制作可拖拽可点击的悬浮球

    兼容mouse事件和touch事件,支持IE9及其以上 效果展示:https://jsfiddle.net/shifeng/7xebf3u0/ // index.html <!DOCTYPE h ...

  7. HBase RowKey与索引设计

    1. HBase的存储形式 hbase的内部使用KeyValue的形式存储,其key时rowKey:family:column:logTime,value是其存储的内容. 其在region内大多以升序 ...

  8. IScroll5不能滑到最底端的解决办法

    IScroll总体上用起来比较简单,但是如果用不好的可能会产生底部一点滚动不上去的问题. 环境:weui+iscroll5 整体布局及id如下 searchbarwrapper   divscroll ...

  9. (三)初探maven之使用IDE

    一.在IDE中使用maven 打开Eclipse,在菜单栏依次选中window   => preferences  => Maven  => Installations , 然后添加 ...

  10. [算法竞赛入门经典] 象棋 ACM/ICPC Fuzhou 2011, UVa1589 较详细注释

    Description: Xiangqi is one of the most popular two-player board games in China. The game represents ...