第 2 章 用于 Real Time 的 RHEL 上的内存管理
实时系统使用虚拟内存系统,其中由用户空间应用程序引用的地址转换为物理地址。翻译是通过底层计算系统中页表和地址转换硬件的组合来实现的。在程序和实际内存之间转换机制的一个优点是,操作系统在需要或 CPU 请求时可以交换页面。
实时从二级存储到主内存交换页面,之前使用的页表条目被标记为无效。因此,即使在普通内存压力下,操作系统也可以从一个应用程序中检索页面并将其提供给另一个应用程序。这可能导致无法预计的系统行为。
内存分配实现包括要求分页机制和内存锁定(mlock
())系统调用。
在不同缓存和 NUMA 域中共享 CPU 的数据信息可能会导致流量问题和瓶颈。
在编写多线程应用程序时,在设计数据定位前考虑机器拓扑。拓扑是内存层次结构,包括 CPU 缓存和 Non-Uniform Memory Access(NUMA)节点。
2.1. 需求分页
需求分页与页面交换的分页系统类似。系统在需要或 CPU 需求时,载入二级内存中存储的页面。程序生成的所有内存地址都通过处理器中的地址转换机制。然后,地址将从进程特定虚拟地址转换为物理内存地址。这称为虚拟内存。转换机制中的两个主要组件是页表和翻译缓冲区(TLBs)
页表
页面表是物理内存中的多级表,其中包含虚拟到物理内存的映射。这些映射可由处理器中的虚拟内存转换硬件读取。
带有分配的物理地址的页表条目被称为常驻工作集。当操作系统需要释放其他进程的内存时,它可以从常驻工作集交换页面。在交换页面时,对此页面内的虚拟地址的任何引用都会产生页面错误,并导致页面重新分配。
当系统在物理内存上极低时,交换进程会启动到thrash,这会持续从进程中传输页面,并且永远不会允许进程完成。您可以通过在 /proc/vmstat
文件中查找 pgfault
值来监控虚拟内存统计信息。
翻译的缓冲
转换 Lookaside Buffers(TLBs)是虚拟内存转换的硬件缓存。任何具有 TLB 的处理器内核都会通过启动内存读取页表条目并行检查 TLB。如果虚拟地址的 TLB 条目有效,则内存读取将中止,并且 TLB 中的值用于地址转换。
TLB 在参考的本地原则上运行。这意味着,如果代码在很长一段时间内一直保留在一个内存区域(如循环或调用相关功能),则 TLB 引用避免了地址转换的主内存。这可显著加快处理时间。
在编写确定性和快速代码时,请使用可保持参考位置的功能。这意味着使用循环而不是递归。如果 recursion 不可避免,请将递归调用放在函数的末尾。这称为 tail-recursion,这使得代码在相对较小的内存区域工作,并避免从主内存调用表转换。