linux内存不足时缩减缓存,Linux内存及页面缓存管理概要总结

物理内存管理

页面内存管理

Linux把物理内存划分为若干个大小相同(通常是4k)的页面,每个页面使用struct page描述,在内核初始化时会根据物理内存大小和页面大小,初始化一个struct page数组mem_map[]对系统中所有的页面进行统一管理。

物理页面描述

使用Node,Zone,Page三级结构进行管理。

对于NUMA计算机,有多个Node,非NUMA计算机则只有一个Node。

每个Node中有3个Zone,分别为DMA,Normal和HighMem(有的还有DMA32等其他Zone,不是必须,有的有特殊用途,此处忽略)。在32位CPU中,DMA为从3G开始的16M地址空间,Normal为接下来的880M地址空间,HighMem为最后的128M地址空间。在64位CPU中,由于目前只用了48位地址,共256T地址空间,内核态占用高128T地址空间,所有物理内存都可以被映射到内核,所以没有HighMem Zone(其实也是有的,只是跟32位的有区别)。

Page是内核物理内存管理的最小单位,包含各种该页面内存的状态信息,分配状况等。

物理页面分配

使用Buddy,以2的N次方个页面为单位进行内存分配,主要解决外部碎片问题。

物理页面回收

回收类型

内存中并非所有物理页面都是可以进行回收的,内核占用的页不会被换出,只有与用户空间建立了映射关系的物理页面才会被换出。总的来说,以下这些种物理页面可以被 Linux 操作系统回收:

进程映射所占的页面,包括代码段,数据段,堆栈以及动态分配的“存储堆”( malloc 分配的)。

用户空间中通过 mmap()把文件内容映射到内存所占的页面。

匿名页面(没有映射到文件的都是匿名映射,用户空间的堆和栈):进程用户模式下的堆栈以及是使用 mmap 匿名映射的内存区(共享内存 区)。注:堆栈所占页面一般不被换出。

特殊的用于 slab 分配器的缓存,比如用于缓存文件目录结构 dentry 的 cache,以及用于缓存索引节点 inode 的 cache

tmpfs 文件系统使用的页。

回收时机

周期性的检查:这是由后台运行的守护进程 kswapd 完成的。该进程定期检查当前系统的内存使用情况,当发现系统内空闲的物理页面数目少于特定的阈值时,该进程就会发起页面回收的操作。

“内存严重不足”事件的触发:在某些情况下,比如,操作系统忽然需要通过伙伴系统为用户进程分配一大块内存,或者需要创建一个很大的缓冲区,而当时系统中 的内存没有办法提供足够多的物理内存以满足这种内存请求,这时候,操作系统就必须尽快进行页面回收操作,以便释放出一些内存空间从而满足上述的内存请求。 这种页面回收方式也被称作“直接页面回收”。

swap内存管理

在低速磁盘上选定一块空间,以页面大小(通常是4k)为单位划分空间(开头还有4k的swap分区描述结构),以页面为单位进行管理。

虚拟内存管理

内核态虚拟内存管理

内核态虚拟内存分配

使用slab分配器(嵌入式系统使用轻量级slub分配器,大型服务器使用支持大量大内存分配的slob分配器),主要解决外部碎片问题。

在此基础上创建一系列的页面缓存,比如task_struct,inode,file缓存。

kmalloc使用slab创建一系列以2的N次方大小为单位的页面缓存进行内存分配,所以分配的内存的物理连续的,且地址空间位于Normal Zone。

vmalloc与vmalloc使用的分配方法稍有不同,分配的内存可能是屋里不连续的,且映射空间在HighMem Zone。

用户态虚拟内存分配

malloc进行内存分配实际上是通过brk和mmap函数实现的,brk和mmap函数仅仅是在进程的task_struc中创建新的vma,以及为进程创建新的页表,并未进行实际内存分配。

实际内存分配发生在当用户初次访问内存引起的缺页中断中,使用buddy分配器以页面为单位进行分配。

页面缓存管理

命名页面,比如所有的文件或者块设备所对应的页面缓冲,也就是有后备存储的缓冲。在Linux的所有文件或者块设备的IO过程中,除了使用DirectIO方式之外,全部会使用内存进行缓冲。如果使用read/write方式,则会有块缓冲,如果使用mmap方式,则会使用页缓冲。在新版的Linux内核中,这二者已经融为一体,使用相同的不同的数据结构描述相同的数据页面,且对于inode相同的文件或块设备,其缓冲在整个内核中只有唯一的一份。

匿名页面,比如用户态分配的内存,无论是brk还是mmap分配,也就是没有后备存储的页面。

在页面回收时,对于命名页面,如果为脏则陷入后备存储后丢弃,对于匿名页面,如果为脏则写入swap存储。

页面缓存回收使用LRU2Q算法,将不常用的页面释放掉。

用户态可以对命名页面进行控制的函数

fadvise系列函数,控制缓存页面的加载,丢弃。

mlock系列函数,锁定或解锁缓存页面。

mincore函数, 查看命名页面状态。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值