Linux 内存管理:理解页表、交换和内存分配

Linux Memory Management: Understanding Page Tables, Swapping, and Memory Allocation

简介

内存管理是现代操作系统的关键方面,它确保系统内存的有效分配和释放。Linux 作为一个强大且广泛使用的操作系统,采用了复杂的技术来有效地管理内存。理解诸如页表、交换和内存分配等关键概念对于系统管理员、开发人员以及任何在底层使用 Linux 的人来说至关重要。

本文深入探讨 Linux 内存管理,探索页表的复杂性、交换的作用以及不同的内存分配机制。到最后,读者将深入了解 Linux 如何处理内存以及如何优化内存以获得更好的性能。

理解 Linux 页表

什么是虚拟内存?

像大多数现代操作系统一样,Linux 实现了虚拟内存,为进程提供了一个巨大的连续内存空间的错觉。虚拟内存实现了高效的多任务处理、进程之间的隔离以及对超过物理可用内存的内存的访问。促进虚拟内存的核心机制是页表,它将虚拟地址映射到物理内存位置。

页表如何工作

页表是 Linux 内核使用的数据结构,用于将虚拟地址转换为物理地址。由于内存是以固定大小的块(称为,通常大小为 4KB)进行管理的,因此每个进程都维护一个页表,该页表跟踪哪些虚拟页对应于哪些物理页。

多级页表

由于现代计算中存在大量的地址空间(例如,64 位架构),单级页表效率低下且会消耗过多内存。相反,Linux 使用分层的多级页表方法

  1. 单级页表(用于内存较小的旧式 32 位系统)

  2. 二级页表(通过将页表分解为更小的块来提高效率)

  3. 三级页表(在某些架构中使用,以获得更好的可扩展性)

  4. 四级页表(现代 64 位 Linux 系统中的标准,将地址分解为更小的部分)

每个级别都有助于定位页表的下一部分,直到最后一个条目,其中包含实际的物理地址。

页表条目 (PTE) 及其组件

页表条目 (PTE) 包含重要信息,例如

  • 物理页帧号。

  • 访问控制位(读取/写入/执行权限)。

  • 存在位(指示页面是在 RAM 中还是已交换到磁盘)。

  • 脏位(指示页面是否已被修改)。

  • 引用位(用于页面置换算法)。

性能考虑因素:转换后备缓冲器 (TLB)

由于为每次内存访问遍历多级页表会很慢,因此现代 CPU 使用称为转换后备缓冲器 (TLB) 的硬件缓存。TLB 存储最近的虚拟地址到物理地址的转换,通过减少所需的内存访问次数来大幅提高性能。

Linux 中的交换:将内存扩展到物理限制之外

什么是交换?

交换是一种机制,当内存不足时,Linux 会将不常用的内存页从 RAM 移动到磁盘(交换空间)。此过程允许系统处理超出可用物理内存的工作负载。

交换如何工作

Linux 保留了专用的交换空间,可以是

  • 交换分区(为交换指定的单独磁盘分区)。

  • 交换文件(文件系统上用作交换空间的文件)。

当进程需要的内存超过可用内存时,内核会决定使用页面置换算法交换出哪些页面。

页面置换算法

Linux 采用不同的算法来决定要交换出哪些页面

  • 最近最少使用 (LRU):最长时间未使用的页面首先被交换。

  • 最近未使用 (NRU):页面根据其访问位和修改位进行分类。

  • 时钟算法:LRU 的简化版本,可有效近似使用情况。

管理交换使用

swappiness 参数控制 Linux 交换页面的积极程度。该值范围为 0 到 100

  • 低值(例如,10-20): 尽可能优先将页面保留在 RAM 中。

  • 高值(例如,60-100): 更积极地交换以释放 RAM。

要检查和调整 swappiness

cat /proc/sys/vm/swappiness
sudo sysctl vm.swappiness=30

要监视交换使用情况

free -m
vmstat 2
swapon -s
优化交换性能
  • 使用快速 SSD 进行交换存储,以减少性能下降。

  • 确保足够的 RAM 以最大限度地减少交换。

  • 根据工作负载需求调整 swappiness

Linux 中的内存分配

物理内存与虚拟内存分配

Linux 将内存分为三个区域

  • DMA(直接内存访问):为需要直接内存访问的硬件保留。

  • 普通区域:内核和用户进程可用的内存。

  • 高位内存:当物理内存超过直接可寻址范围时使用。

内核内存分配机制
  1. 伙伴系统:以 2 的幂次方块分配内存,以减少碎片。

  2. Slab 分配器:有效地管理频繁分配/释放的小对象。

  3. SLOB 和 SLUB 分配器:针对不同工作负载优化的替代分配策略。

用户空间内存分配
  • malloc():在用户空间中分配内存。

  • brk() & sbrk():调整进程堆大小。

  • mmap():直接从内核分配大内存区域。

处理内存不足 (OOM) 情况

当内存耗尽时,Linux OOM Killer 会选择并终止进程以释放 RAM。可以通过以下方式检查日志

dmesg | grep -i 'oom'

实践见解和最佳实践

监视内存使用情况
  • tophtop 用于实时监视。

  • free -m 用于内存统计信息。

  • /proc/meminfo 用于详细的见解。

  • pmap 用于特定于进程的内存映射。

优化内存性能
  • 调整 swappiness 以平衡 RAM 和交换使用。

  • 使用内存控制组来限制进程内存消耗。

  • 使用巨页进行大型内存分配。

  • 优化应用程序内存占用以防止过度交换。

结论

理解 Linux 内存管理——页表、交换和内存分配——使系统管理员和开发人员能够有效地优化性能和排除问题。借助监视、调整和增强内存处理的工具和技术,Linux 仍然是一个强大而灵活的操作系统,适用于各种工作负载。

通过掌握这些概念,您可以确保您的系统高效运行并在内存约束下良好响应,从而提高整体性能和可靠性。

George Whittaker 是 Linux Journal 的编辑,也是一位定期撰稿人。George 撰写技术文章已有二十年,并且是 Linux 用户超过 15 年。在空闲时间,他喜欢编程、阅读和游戏。

加载 Disqus 评论