对于进程而言,Linux操作系统采用的是虚拟内存管理技术,这使得进程都拥有了独立的虚拟内存空间。该内存空间的大小为4G的线性虚拟空间,进程只需关注自己可以访问的虚拟地址,无需直到物理地址的映射情况。利用这种虚拟地址不但更安全(用户不能直接访问物理内存),而且用户程序可以使用比实际物理内存更大的地址空间。
4GB的进程地址空间会被分成两个部分——用户空间与内核空间。用户地址空间是0~3GB(0xC0000000),内核地址空间占据3~4GB。用户进程在通常情况下只能访问用户空间的虚拟地址,不能访问内核空间虚拟地址。只有用户进程使用系统调用(代表用户进程在内核态执行)时才可以访问到内核空间。每当进程切换,用户空间就会跟着产生变化;而内核空间是由内核负责映射,它并不会跟着进程改变,是固定的。内核空间地址有自己对应的页表,用户进程各自有不同的页表。每个进程的用户空间都是完全独立、互不相干的。
进程的资源数据在虚拟内存上的分布如下图所示,注意进程在虚拟空间上的存储的数据不是按地址固定,其大小也不固定,进程很有可能使用了其中一小部分。
在这里插入图片描述

如图所示,用户空间包括以下几个功能区域(通常也称之为“段(segment)”):
(1) 程序代码段:具有只读属性,包含程序代码(.init和.text)和只读数据(.rodata)。
(2)数据段:存放的是全局变量和静态变量。 其中初始化数据段(.data)存放显示初始化的全局变量和静态变量,未初始化数据段,此段通常也被称为BSS段(.bss),存放未进行显示初始化的全局变量和静态变量。
(3)栈:由系统自动分配释放,存放函数的参数值、局部变量的值、返回地址等。
(4)堆:存放动态分配的数据,一般由程序动态分配和释放,若程序不释放,程序结束时可能由操作系统回收。例如,使用malloc()申请空间。
(5)共享库的内存映射区域:这是Linux动态链接器和其他共享库代码的映射区域。

Logo

更多推荐