Linux缓存机制:提高系统性能的关键一页 (linux 缓存机制页)

Linux是一款广泛使用的操作系统,拥有着良好的稳定性和可靠性。在运行过程中,Linux会自动对一些重复操作所使用的数据进行缓存,以提高系统的性能。这种缓存机制在Linux系统中被称作页面缓存,是优化系统性能的关键一页。

一、页面缓存的概念

页面缓存,即Page Cache,是Linux系统自带的一种缓存机制。它将磁盘中的文件数据全部读入内存,缓存住这些数据,使得后续的读操作可以直接从内存中获取,而无需再从磁盘中读取。这样可以大大缩短I/O操作的时间,提高系统性能。

二、页面缓存的工作原理

在Linux系统中,每一个文件都被抽象为一个inode,inode是文件系统数据结构中的一部分,它包含了文件的元数据(例如大小、权限等)以及指向文件内容的指针。当用户运行一个应用程序读取某个文件时,Linux会通过读取该文件的inode来获取文件的物理位置。如果该文件存在于页面缓存中,则直接从缓存中读取数据,否则就需要从磁盘中读取数据。

页面缓存机制的本质是将磁盘中的文件数据全部读入内存,并将其缓存住,使得后续的读操作可以直接从缓存中获取。在实现上,Linux会为每一个文件打开一个缓存页面列表,将文件的所有缓存页面链接在一起,形成一个链表。当应用程序请求读取某个文件时,Linux会检查该文件的缓存页面列表,如果该页面已经在内存中,则直接返回缓存页面的数据;否则就需要从磁盘中读取该页面的数据,并将其添加到缓存页面列表中。

当应用程序进行写操作时,页面缓存会将用户写入的数据暂存在内存中,并且在一定时间后写回磁盘。在这个过程中,Linux会将正在写入的数据标记为脏页,同时在缓存中保留一份该页面的拷贝,以便后续的读操作能够直接从缓存中获取。在内存空间不足时,Linux会优先将脏页写回磁盘,并释放掉这部分内存空间。

除了文件系统数据的缓存外,页面缓存还会缓存进程的内存数据。在程序运行时,Linux会将进程的数据(例如栈、堆等)保存在内存中,而这部分数据同样可以被缓存到页面中,以避免反复的IO操作。

三、页面缓存的优势

页面缓存作为Linux系统的核心功能之一,在提高系统性能、减少IO操作等方面具有重要的作用。

页面缓存可以大大缩短I/O操作的时间,提高系统性能。相对于从磁盘中读取数据,从内存中读取数据的速度相对要快得多,因为读取内存数据的速度普遍比访问硬盘的速度快10倍以上。这意味着,使用页面缓存可以大大降低I/O操作的时间延迟,提高数据读取的速度,从而为系统的性能提供了有力的支持。

页面缓存可以减少对磁盘的访问次数,从而减少对硬件的使用量。这对于频繁进行IO操作的应用程序尤为重要。通过减少对磁盘的访问,可以降低磁盘使用寿命,延长磁盘的使用寿命。

页面缓存是一种最有效的提高系统性能的方式之一。它通过减少文件IO操作来缩短系统的响应时间,同时也为系统提供了更多的内存空间,使得系统更加稳定可靠。

四、页面缓存的缺陷

尽管页面缓存是一种很有用的技术,但是它在某些情况下也会带来一些问题。

页面缓存会占用大量的内存空间。特别是在处理大型文件时,缓存区可能会占用数百MB的内存空间,这可能会导致其他应用程序的性能和响应能力下降。对于一些资源有限的设备,例如个人电脑和嵌入式设备等,建议尽量避免大规模使用页面缓存。

页面缓存可能会引起一些奇怪的现象,例如文件的修改并不会立即反映在内存中。由于页面缓存将文件的数据保存在内存中,因此它可能会导致文件的修改被延迟写入磁盘,从而导致在重启时数据的丢失。

页面缓存可能会成为一个安全漏洞。如果攻击者能够获取系统中的缓存数据,并且能够在其中进行恶意篡改,那么系统的安全性将会受到严重的威胁。因此,在使用页面缓存时,需要进行一些必要的安全措施。

五、结论

页面缓存是Linux系统中非常重要的一部分,它可以提高系统性能、减少对硬件的使用等,同时也为系统的稳定性和可靠性提供了保障。当然,页面缓存也存在一些缺点,需要注意一些安全和可用性问题。因此,在使用页面缓存时,需要谨慎考虑各种因素,以确保系统的稳定性和安全性。

相关问题拓展阅读:

Linux 内核的内存管理 – 概念

Concepts overview — The Linux Kernel documentation

Linux中的内存管理是一个复杂的系统,经过多年的发展,它包含越来越多的功能,以支持从 MMU-less microcontrollers 到 supercomputers 的各种系统。

没有MMU内存管理的系统被称为 nommu ,它值得写一份专门的文档进行描述。

尽管有些概念是相同的,这里我们假设MMU可用,CPU可以将虚拟地址转换为物理地址。

计算机系统中的物理内存是有限资源,即便支持内存热插拔,其可以安装的内存也有限的。物理内存不一定必须是连续的;它可以作为一组不同的地址范围被访问。此外,不同的CPU架构,甚至同架构的不同实现对如何定义这些地址范围都是不同的。

这使得直接处理物理内存异常复杂,为了避免这种复杂性,开发了

虚拟内存 (virtual memory)

的概念。

虚拟内存从应用软件中抽象出物理内存的细节,只允许在物理内存枣神中保留需要的信息

(demand paging)

,并提供一种机制来保护和控制进程之间的数据共享。

通过虚拟内存,每次内存访问都访问一个

虚拟地址

。当CPU对从系统内存读取(或写入)的指令进行解码时,它将该指令中编码的虚拟地址转换为内存控制器可以理解的物理地址。

物理内存被切分为

页帧 page frames

页 pages

。页的大小是基于架构的。一些架构允许从几个支持的值中选择页大小;此选择在内核编译时设置到内核配置。

每个物理内存页都可以映射为一个或多个

虚拟页(virtual pages)

。映射关系描述在

页表(page tables)

中,页表将程序使用的虚拟地址转换为物理内存地址。页表以层次结构组织。

更底层的表包含软件使用的实际内存页的物理地址。较高层的表包含较低层表页的物理地址。顶层表的指针驻留在寄存器中。

当CPU进行地址转换的时候,它使用寄存器访问顶级页表。

虚拟地址的高位,用于顶级页表的条目索引。然后,通过该条目访问下级,下级的虚拟地址位又作为其下下级页表的索引。虚拟地址的更低位定义实际页内的偏移量。

地址转换需要多次内存访问,而内存访问相对于CPU速度来说比较慢。为了避免在地址转换上花费宝贵的处理器周期,CPU维护着一个称为

TLB

(Translation Lookaside Buffer)的用于地址转换缓存(cache)。通常TLB是非常稀缺的资源,需要大内存工作应用程序会因为TLB未命中而影响性能。

很多现代CPU架构允许页表的高层直接映射到内存页。例如,x86架构,可以通过二级、三级页表的条目映射2M甚至1G内存页。在Linux中,这些内存页称为

大页 (Huge)

。大页的使用显著降低了TLB的压力,提高了TLB命中率,从而提高了系统的整体性能。

Linux提供两种机制开启使用大页映射物理内存。

之一个是

HugeTLB

文件系统,即

hugetlbfs

。它是一个伪文件系统,使用RAM作为其存储。在此文件系统中创建的文件,数据驻留在内存中,并使用大页进行映射。

关于 HugeTLB Pages

另一个被称为

THP (Transparent HugePages)

,后出的开启大页映射物理内存的机制。

hugetlbfs

不同,hugetlbfs要求用户和/或系统管理员配置系统内存的哪些部分应该并可以被大页映射;THP透明地管理这些映射并获取名称。

关于 Transparent Hugepage Support

通常,硬件对不同物理内存范围的访问方式有所限制。某些情况下,设备不能对所有可寻址内存执行DMA。在其他情况下,物理内存的大小超过虚拟内存的更大可寻址大小,需要采取改岩大特殊措施来访问部分内存。还有些情况,物理内存的尺寸超过了虚拟内存的更大可寻址尺寸,需要采取特殊措施来访问部分内存。

Linux根据内存页的使用情况,将其组合为多个

zones

。比如, ZONE_DMA 包含设备用于DMA的内存, ZONE_HIGHMEM 包含未永久映射到内核核竖地址空间的内存, ZONE_NORMAL 包含正常寻址内存页。

内存zones的实际层次架构取决于硬件,因为并非所有架构都定义了所有的zones,不同平台对DMA的要求也不同。

多处理器机器很多基于

NUMA

(Non-Uniform Memory Access system – 非统一内存访问系统 )架构。 在这样的系统中,根据与处理器的“距离”,内存被安排成具有不同访问延迟的

banks

。每个

bank

被称为一个

node

,Linux为每个

node

构造一个独立的内存管理子系统。

Node

有自己的zones、free&used页面列表,以及各种统计计数器。

What is NUMA?

NUMA Memory Policy

物理内存易失,将数据放入内存的常见情况是读取文件。读取文件时,数据会放入

页面缓存(page cache)

,可以在再次读取时避免耗时的磁盘访问。同样,写文件时,数据也会被放入

页面缓存

,并最终进入存储设备。被写入的页被标记为

脏页(dirty page)

,当Linux决定将其重用时,它会将更新的数据同步到设备上的文件。

匿名内存 anonymous memory

匿名映射 anonymous mappings

表示没有后置文件系统的内存。这些映射是为程序的stack和heap隐式创建的,或调用mmap(2)显式创建的。通常,匿名映射只定义允许程序访问的虚拟内存区域。读,会创建一个页表条目,该条目引用一个填充有零的特殊物理页。写,则分配一个常规物理页来保存写入数据。该页将被标记为脏页,如果内核决定重用该页,则脏页将被交换出去

swapped out

纵贯整个系统生命周期,物理页可用于存储不同类型的数据。它可以是内核内部数据结构、设备驱动DMA缓冲区、读取自文件系统的数据、用户空间进程分配的内存等。

根据内存页使用情况,Linux内存管理会区别处理。可以随时释放的页面称为

可回收(reclaimable)

页面,因为它们把数据缓存到了其他地方(比如,硬盘),或者被swap out到硬盘上。

可回收页最值得注意的是

页面缓存

匿名页面

在大多数情况下,存放内部内核数据的页,和用作DMA缓冲区的页无法重用,它们将保持现状直到用户释放。这样的被称为

不可回收页(unreclaimable)

然而,在特定情况下,即便是内核数据结构占用的页面也会被回收。

例如,文件系统元数据的缓存(in-memory)可以从存储设备中重新读取,因此,当系统存在内存压力时,可以从主内存中丢弃它们。

释放可回收物理内存页并重新调整其用途的过程称为

(surprise!) reclaim

Linux支持异步或同步回收页,取决于系统的状态。

当系统负载不高时,大部分内存是空闲的,可以立即从空闲页得到分配。

当系统负载提升后,空闲页减少,当达到某个阈值(

low watermark

)时,内存分配请求将唤醒

kswapd

守护进程。它将以异步的方式扫描内存页。如果内存页中的数据在其他地方也有,则释放这些内存页;或者退出内存到后置存储设备(关联

脏页

)。

随着内存使用量进一步增加,并达到另一个阈值-

min watermark

-将触发回收。这种情况下,分配将暂停,直到回收到足够的内存页。

当系统运行时,任务分配并释放内存,内存变得碎片化。

虽然使用虚拟内存可以将分散的物理页表示为虚拟连续范围,但有时需要分配大的连续的物理内存。这种需求可能会提升。例如,当设备驱动需要一个大的DMA缓冲区时,或当THP分配一个大页时。

内存地址压缩(compaction )

解决了碎片问题。

该机制将占用的页从内存zone的下部移动到上部的空闲页。压缩扫描完成后,zone开始处的空闲页就并在一起了,分配较大的连续物理内存就可行了。

reclaim

类似,

compaction

可以在

kcompactd守护进程中异步进行,也可以作为内存分配请求的结果同步进行。

在存在负载的机器上,内存可能会耗尽,内核无法回收到足够的内存以继续运行。

为了保障系统的其余部分,引入了

OOM killer

OOM killer

选择牺牲一个任务来保障系统的总体健康。选定的任务被killed,以期望在它退出后释放足够的内存以继续正常的操作。

关于linux 缓存机制页的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。


数据运维技术 » Linux缓存机制:提高系统性能的关键一页 (linux 缓存机制页)