标签:字符串常量 lin mmap table 请求 访问 address span enter
这篇文章主要记录一下c程序运行时内存空间如何使用。(摘抄自网络)
在一个多任务操作系统中的每个进程都运行在它自己的内存“沙箱”中。这个沙箱是一个虚拟地址空间(virtual address space),在 32 位系统中它总共有 4GB 的内存地址空间,包含内核空间和用户空间:
这些虚拟地址是通过内核页表(page table)映射到物理地址的,并由操作系统内核维护。在典型的Linux 中,内核/用户空间的划分比例为1:3。但是,这并不意味着内核就使用了1G物理内存,它只使用了很少一部分可用的地址空间映射到其所需要的物理内存。内核空间的页表被标记,因此,如果一个用户模式的程序尝试去访问它,将触发一个页面故障错误。
在 Linux 中,内核空间是始终存在的,并且在所有进程中都映射相同的物理内存。内核代码和数据总是可寻址的,准备随时去处理中断或者系统调用。相比之下,用户模式中的地址空间,在每次进程切换时都会发生变化:
一个 Linux 进程的标准段布局如下:
检查栈的增长是否正常。如果栈的大小低于 RLIMIT_STACK
的值(一般是 8MB 大小),那么这是一个正常的栈增长,否则可能是发生了未知问题。这是一个栈大小按需调节的常见机制。但是,栈的大小达到了上述限制,将会发生一个栈溢出,并且,程序将会收到一个段故障Segmentation Fault错误。当映射的栈区为满足需要而扩展后,在栈缩小时,映射区域并不会收缩。访问任何未映射的内存区域都是非法的,并将触发一个页面故障,导致段故障。但
动态栈增长是唯一例外的情况,当它去访问一个未映射的内存区域是允许的。
MMAP_THRESHOLD
设置的字节数,它的缺省值是 128 kB,可以通过mallopt()去调整这个设置值。内存映射段下面是堆,堆提供运行时内存分配,它分配的数据生存期要长于分配它的函数。大多数编程语言都为程序提供了堆管理支持,在 C 中,堆分配的接口是 malloc() 一族。
如果在堆中有足够的空间可以满足内存请求,它可以由编程语言运行时来处理内存分配请求,而无需内核参与。否则将通过 brk() 系统调用来扩大堆以满足内存请求所需的大小。堆管理比较复杂,在面对我们程序的混乱分配模式时,它通过复杂的算法,努力在速度和内存使用效率之间取得一种平衡。堆也会出现碎片化
接下来是数据段,用于保存在源代码中已初始化的全局变量、静态变量的内容。这个内存区域是非匿名的。它映射了程序的二进值镜像上的一部分,即在源代码中给定初始化值的全局变量、静态变量内容。
最后关于变量保存位置:
1、经过初始化的全局变量和静态变量保存在数据段中。
2、未经初始化的全局变量和静态变量保存在BSS段。
3、函数内部声明的局部变量保存在堆栈段中。
4、const修饰的全局变量保存在文本段中,const修饰的局部变量保存在堆栈段中。
5、字符串常量保存在文本段中。
标签:字符串常量 lin mmap table 请求 访问 address span enter
原文地址:https://www.cnblogs.com/caidi/p/10179013.html