![虚拟地址空间中的页面大小是如何确定的?](https://linux22.com/image/36198/%E8%99%9A%E6%8B%9F%E5%9C%B0%E5%9D%80%E7%A9%BA%E9%97%B4%E4%B8%AD%E7%9A%84%E9%A1%B5%E9%9D%A2%E5%A4%A7%E5%B0%8F%E6%98%AF%E5%A6%82%E4%BD%95%E7%A1%AE%E5%AE%9A%E7%9A%84%EF%BC%9F.png)
Linux 使用虚拟内存系统,其中所有地址都是虚拟地址而不是物理地址。这些虚拟地址由处理器转换为物理地址。
为了使这种转换更容易,虚拟内存和物理内存被分为页。每一页都有一个唯一的编号;页框号。
有些页面大小可以是 2 KB、4 KB 等。但是这个页面大小数字是如何确定的呢?是否受到架构尺寸的影响?例如,32 位总线将具有 4 GB 地址空间。
答案1
您可以通过以下命令查询系统的配置来找出系统的默认页面大小getconf
:
$ getconf PAGE_SIZE
4096
或者
$ getconf PAGESIZE
4096
笔记:上述单位通常以字节为单位,因此 4096 等于 4096 字节或 4kB。
这是硬连线在 Linux 内核的源代码中的:
例子
$ more /usr/src/kernels/3.13.9-100.fc19.x86_64/include/asm-generic/page.h
...
...
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT 12
#ifdef __ASSEMBLY__
#define PAGE_SIZE (1 << PAGE_SHIFT)
#else
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#endif
#define PAGE_MASK (~(PAGE_SIZE-1))
换档怎么给你4096?
当您移位时,您正在执行乘以 2 的二进制乘法。因此,实际上向左移位 ( 1 << PAGE_SHIFT
) 就是进行 2^12 = 4096 的乘法。
$ echo "2^12" | bc
4096
答案2
硬件(具体来说,内存管理单元,它是 CPU 的一部分)决定了可能的页面大小。与处理器寄存器大小无关,仅与地址空间大小有间接关系(因为 MMU 决定两者)。
几乎所有架构都支持 4kB 页面大小。有些架构支持较大的页面(少数也支持较小的页面),但 4kB 是非常普遍的默认值。
Linux 支持两种页面大小:
- 正常大小的页面,我相信在所有架构上默认情况下都是 4kB,尽管某些架构允许其他值,例如 16kBARM64或 8kB、16kB 或 64kBIA64。这些对应于 MMU 上最深层次的描述符(Linux 称之为英语口语考试)。
- 大页面,如果编译为 (
CONFIG_HUGETLB_PAGE
是必要的,并且CONFIG_HUGETLBFS
对于大多数用途也是如此)。这对应于 MMU 描述符的第二深级别(Linux 称之为 PMD)(或者至少通常是这样,我不知道这是否适用于所有体系结构)。
页面大小是内存占用、内存使用量和速度之间的折衷。
- 较大的页面大小意味着当部分使用页面时会产生更多浪费,因此系统会更快耗尽内存。
- 更深的 MMU 描述符级别意味着更多的内核内存用于页表。
- 更深的MMU描述符级别意味着更多的时间花在页表遍历上。
对于大多数应用程序来说,较大页面大小的收益很小,但成本却很高。这就是大多数系统仅使用正常大小的页面的原因。
您可以使用以下命令查询系统上的(正常)页面大小getconf
实用程序或 C 函数sysconf
。
$ getconf PAGE_SIZE
4096
使用大页面需要在其中安装hugetlbfs
文件系统和mmap
ping 文件。
答案3
处理器确定可用的页面大小。对于大多数用途,x86 和 x86_64 处理器上硬件实现的页面大小为 4kb。然而,如果操作系统愿意,可以一次分配多个页面,从而在软件中有效地实现 8kb、16kb 或 32kb 页面。
x86 和 x86_64 处理器还可以分别将 4mb 和 2mb 页面与标准 4kb 页面混合。如果使用该功能,它将主要用于分配内核空间。
答案4
页大小主要取决于处理器架构。在x86上,从引入保护模式的386处理器时代开始,页面大小一直是4 kB。
在 x64 模式下,还可以存在大小为 2 MB 的大页面。然而,使用它们有点复杂。
您可以在以下位置找到有关页面大小的更多信息维基百科文章