一、内核空间和用户空间

对于32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方)。操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的权限。为了保证用户进程不能直接操作内核,保证内核安全,操作系统将虚拟空间划分为两部分,一部分是内核空间,一部分是用户空间。针对Linux操作系统,将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF)供内核使用,称为内核空间(window os占用2G),而其他的(3G)字节(从虚拟地址0x00000000到0xBFFFFFFF),供各个进程使用,称为用户空间。每个进程都可以通过系统调用进入到内核。其中在Linux系统中,进程的用户空间是独立的,而内核空间是共有的(每个进程都认为自己有4G的空间),进程切换时,用户空间切换,内核空间不变。

linux 下C程序在运行时的内存分布情况教程

二、程序在运行时内存的分布情况

(1)代码段(Text segement):


通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域属于只读。

C语言中使用char *p = "linux";定义字符串时,字符串"linux"实际被分配在代码段。

这个地方还有一种说法:

".rodata"段存放的是只读数据,一般是程序里面的只读变量(如const修饰的变量)和字符串常量。

(个人理解:究竟是代码段还是只读数据段都不重要,只要知道只读即可)

(2)数据段(data segment):

存放程序中已显式初始化为非零的全局变量和static修饰的局部变量的一块内存区域。

(普通局部变量分配在栈上,静态局部变量分配在.data段)

(3)BSS段(Block Started by Symbol segment):(又叫ZI(zero initial)段)

未初始化或显式初始化为0的全局变量放在bss段。

执行程序在运行时又多出两个区域:栈区和堆区。

注意区分:数据段(.data)和bss段的区别和联系:二者本来没有本质区别,都是用来存放C程序中的全局变量的。区别在于把显示初始化为非零的全局变量存在.data段中,而把显式初始化为0或者并未显式初始化(C语言规定未显式初始化的全局变量值默认为0)的全局变量存在bss段。

(4)栈区:

运行时自动分配、自动回收:栈是自动管理的,不许程序员干预;

栈区是从高地址位向低地址(虚拟地址)位增长的,是一块连续的内存区域,最大容量是由系统预先定义好的,申请的栈空间超过这个界限时会提示溢出,用户能从栈中获取的空间较小。

栈内存由于反复使用,每次使用后程序不会去清理,因此分配到时保留原来的值。

(5)堆区:

由程序员申请分配和释放,需要写代码去申请malloc和释放free;

堆是从低地址位向高地址位增长(虚拟地址),采用链式存储结构。频繁的 malloc/free造成内存空间的不连续,产生碎片。当申请堆空间时库函数是按照一定的算法搜索可用的足够大的空间。因此堆的效率比栈要低的多。

REF:

https://blog.csdn.net/omnispace/article/details/80077769

https://blog.csdn.net/weixin\_39731083/article/details/82345157

http://www.360doc.com/content/12/0405/00/1671317\_200882538.shtml

https://blog.csdn.net/b5w2p0/article/details/39581559

标签: 内存, linux, 内核, 空间, 全局变量, 程序, 初始化, 显式

相关文章推荐

添加新评论,含*的栏目为必填