虚拟内存布局
虚拟地址空间大小:
- 32位虚拟地址空间 [0 ~ 2^32 - 1] 总共4GB
- 64位虚拟地址空间 [0 ~ 2^64 - 1] 总共16 777 216TB
不管是运行在用户态还是内核态,都需要使用虚拟地址,这是因为计算机硬件要求的,CPU要经过地址转换得到最终的物理地址,软件必须服从硬件的规定。
内核态的虚拟空间和某一个程序没有关系,所有程序通过系统调用进入到内核之后,看到的虚拟地址空间都是一样的。
-
32 位虚拟地址空间中,[0x0000 0000, 0xBFFF FFFF] 的 3GB 空间用作用户态,是每一个应用程序可以使用的虚拟地址范围,[0xC000 0000, 0xFFFF FFFF] 的 1GB 空间用作内核态,是给操作系统内核使用的虚拟地址范围
-
每个用户程序都使用相同的虚拟地址空间 [0x0000 0000, 0xBFFF FFFF],每个内核程序也使用相同的虚拟地址空间 [0xC000 0000, 0xFFFF FFFF]
-
64 位虚拟地址空间中,低 128T 虚拟地址空间被用作用户态,高 128T 虚拟地址空间被用作内核态,中间留有空洞
用户态虚拟内存布局,从上往下分别是:
-
栈(stack)
-
mmap内存映射区
-
运行时堆区(heap)
-
数据段(.bss和.data)
-
代码段(.text)
其中栈空间是倒着向下增长的,堆区空间是向上增长的,栈和堆是相对增长,消耗中间的地址空间。mmap区和堆区也可以相对增长(64位中mmap区往哪边增长都可以)
内存映射
Linux 中通过将一块虚拟地址内存空间和一个文件对象关联起来,以初始化这块虚拟内存的内容,这个过程称为内存映射(memory mapping)。
这里的文件对象可以是:
- ① Linux文件系统中的普通文件,
- ②