本文主要介绍了一些page reclaim机制中的基本概念。这份文档其实也可以看成阅读ULK第17章第一小节的一个读书笔记。虽然ULK已经读了很多遍,不过每一遍还是觉得有收获。Linux内核虽然不断在演进,但是页面回收的基本概念是不变的,所以ULK仍然值得内核发烧友仔细品味。

一、什么是page frame reclaiming?

在用户进程的内存使用上,Linux内核并没有严格的限制,其实思路是:当系统负荷小的时候,内存都是位于各种cache中,以便提高性能。当系统负荷重(进程数目非常多)的时候,cache中的内存被收回,然后用于进程地址空间的创建和映射。在这样思路的指导下,一开始,内核大手大脚,一直从伙伴系统的free list上分配page frame给用户进程或者各种kernel cache使用,但是系统内存终归是有限的,当伙伴系统的空闲内存下降到一定的水位的时候,系统会从用户进程或者kernel cache中回收page frame到伙伴系统,以便满足新的内存分配的需求,这个过程就是page frame reclaiming。一言以蔽之,page frame reclaiming就是保证系统的空闲内存在一个指定的水位之上。

二、什么时候启动page frame reclaiming?

能不能等到空闲内存用尽之后才启动page frame reclaiming呢?不行,因为在page frame reclaiming的过程中也会消耗内存(例如在页面回收过程中,我们可能会将page frame的数据交换到磁盘,因此需要分配buffer head数据结构,完成IO操作),因此我们必须在伙伴系统中保持一定的水位,以便让page frame reclaiming机制正常工作,以便回收更多的内存,让系统运转下去,否则系统会crash掉。

三、哪些场景可以触发page frame reclaiming?

当分配内存失败的时候触发页面回收是最直观的想法,然而内核的场景没有那么简单,例如在中断上下文中分配内存,这时候我们不能触发page frame reclaiming,因为这时候我们不能阻塞当前进程。此外,有些内存分配的场景是发生在持锁之后(以便对某些资源进行排他性的访问),这时候,我们也不能激活IO操作,进行内存回收。

因此,总结起来,内核在内存回收的思路就是:系统在分配内存的时候就进行检查,如果有需要就唤醒kswapd,让系统的空闲内存的数量保持在一个水平之上,以免将自己逼入绝境。如果没有办法,的确进入了绝境(分配内存失败),那么就直接触发页面回收。具体的场景包括:

1、synchronous page reclaim,即当遭遇分配内存失败的时候,一言不合,然后直接调用page frame reclaiming进行回收。例如:在分配page buffer的时候(alloc_page_buffers),如果分配不成功,直接调用free_more_memory进行内存回收。或者在调用__alloc_pages的时候,如果分配不成功,直接调用try_to_free_pages进行内存回收。当然,其实free_more_memory也是调用try_to_free_pages来实现页面回收的。

2、Suspend to disk(Hibernation)的场景。系统hibernate的时候需要大量内存,这时候会调用shrink_all_memory来回收指定数目的page frame。

3、kswapd场景。Kswapd是一个专门用来进行页面回收的内核线程。

4、slab内存分配器会定时的queue work到system_wq上去,从而会周期性的调用cache_reap来回收slab上的空闲内存。

四、页面回收的策略为何?

首先我们需要对page frame进行分类,主要分成4类:

1、 没有办法回收的page frame。包括空闲页面(已经在free list上面,也就不需要劳驾page frame reclaim机制了)、保留页面(设定了PG_reserved,例如内核正文段、数据段等等)、内核动态分配的page frame、用户进程的内核栈上的page frame、临时性的被锁定的page frame(即设定了PG_locked flag,例如在进行磁盘IO的时候)、mlocked page frame(有VM_LOCKED标识的VMA)

2、 可以交换到磁盘的page frame(swappable)。用户空间的匿名映射页面(用户进程堆和栈上的page frame)、tmpfs的page frame。

3、 可以同步到磁盘的page frame(syncable)。用户空间的文件映射(file mapped)页面,page cache中的page frame(其内容会对应到某个磁盘文件),block device的buffered cache、disk cache中的page frame(例如inode cache)

4、 可以直接释放的page frame。各种内存cache(例如 slab内存分配器)中还没有使用的那些page frame、没有使用的dentry cache。

上面的第二类和第三类有些类似, 其page frame都有后备文件或者磁盘,不过我们可以这么区分。Swappable的page frame,其数据的最终地点就是内存,其后备文件或者磁盘只是为了延伸内存的容量。Syncable的page frame,其数据的最终地点就是磁盘,内存只不过是为了加快速度而已。因此,当回收swappable的页面的时候,需要将page frame的数据保存到后备的磁盘或者文件。而当回收syncable页面的时候,要看page frame是否是dirty的,如果dirty,则需要磁盘操作,否则可以直接回收。

圈定进行页面回收的那些候选page frame很容易(即上面的2、3、4类型的page frame),但是怎么考虑页面回收的先后顺序呢?Linux内核设定的基本规则如下:

1、 尽量不要修改page table。例如回收各种没有使用的内核cache的时候,我们直接回收,根本不需要修改页表项。而用户空间进程的页面回收往往涉及将对应的pte条目修改为无效状态。

2、 除非调用mlock将page锁定,否则所有的用户空间对应的page frame都应该可以被回收。

3、 如果一个page frame被多个进程共享,那么我们需要清除所有的pte entry,之后才能回收该页面。

4、 不要回收那些最近使用(访问)过的page frame,或者说优先回收那些最近没有访问的page frame。

5、 尽量先回收那些不需要磁盘IO操作的page frame。

Linux页面回收概述的更多相关文章

  1. Linux内核入门到放弃-页面回收和页交换-《深入Linux内核架构》笔记

    概述 可换出页 只有少量几种页可以换出到交换区,对其他页来说,换出到块设备上与之对应的后备存储器即可,如下所述. 类别为 MAP_ANONYMOUS 的页,没有关联到文件,例如,这可能是进程的栈或是使 ...

  2. Linux内存管理之页面回收【转】

    转自:http://blog.csdn.net/bullbat/article/details/7311205 请求调页机制,只要用户态进程继续执行,他们就能获得页框,然而,请求调页没有办法强制进程释 ...

  3. linux 设备驱动概述

    linux 设备驱动概述 目前,Linux软件工程师大致可分为两个层次: (1)Linux应用软件工程师(Application Software Engineer):       主要利用C库函数和 ...

  4. linux内存回收机制

    无论计算机上有多少内存都是不够的,因而linux kernel需要回收一些很少使用的内存页面来保证系统持续有内存使用.页面回收的方式有页回写.页交换和页丢弃三种方式:如果一个很少使用的页的后备存储器是 ...

  5. 自学linux——9.Linux的权限概述

    Linux的权限概述 一.      权限概述 1.权限介绍 在多用户(可以不同时)计算机系统的管理中,权限是指某个特定的用户具有特定的系统资源使用权力,像是文件夹.特定系统指令的使用或存储量的限制 ...

  6. JVM垃圾回收概述

    垃圾回收概述 什么是垃圾 什么是垃圾( Garbage) 呢? 垃圾是指在运行程序中没有任何指针指向的对象,这个对象就是需要被回收的垃圾. 如果不及时对内存中的垃圾进行清理,那么,这些垃圾对象所占的内 ...

  7. 自动驾驶QNX,Linux,Autosar概述

    自动驾驶QNX,Linux,Autosar概述 QNX是一个分布式.嵌入式.可规模扩展的实时操作系统.遵循POSIX.1 (程序接口)和POSIX.2 (Shell和工具).部分遵循POSIX.1b( ...

  8. linux内核——1.概述

    1.结构 linux中,我们把操作系统分为内核空间和用户空间.用户通过用户空间与操作系统打交道.用户要通过系统调用访问内核空间.下图为Linux体系结构,shell应该为在最顶层. 系统调用,下面链接 ...

  9. Linux进程实践(1) --Linux进程编程概述

    进程 VS. 程序 什么是程序? 程序是完成特定任务的一系列指令集合. 什么是进程? [1]从用户的角度来看:进程是程序的一次执行过程 [2]从操作系统的核心来看:进程是操作系统分配的内存.CPU时间 ...

随机推荐

  1. Windows Server上用于iSCSI的网卡的必备设置

    如下的修改是iSCSI网卡的推荐配置, 新装起来的Host不要忘记改起来哦. 其原理是强制走iSCSI通讯的网卡立即对到来的TCP报文(segment)做出acknowledge, 从而解决iSCSI ...

  2. 25个iptables常用示例

    本文将给出25个iptables常用规则示例,这些例子为您提供了些基本的模板,您可以根据特定需求对其进行修改调整以达到期望. 格式 iptables [-t 表名] 选项 [链名] [条件] [-j ...

  3. [Algorithm] Tree: Lowest Common Ancestor

    By given a tree structure, task is to find lowest common ancestor: For example, LCA(4, 5) --> > ...

  4. Python源代码 -- C语言实现面向对象编程(基类&派生类&多态)

    背景 python是面向对象的解释性语言.然而python是通过C语言实现的,C语言怎么跟面向对象扯上了关系? C语言能够实现面向对象的性质? 原文链接:http://blog.csdn.net/or ...

  5. Mapnik读取PostGIS数据渲染图片

    __author__ = 'Administrator' # encoding: utf-8 import sys import datetime import mapnik m = mapnik.M ...

  6. C#.NET常见问题(FAQ)-如何把函数名作为参数传递给另一个函数

    在主窗体中使用的还是普通的函数,但是test函数有一个新的参数,就是method   这个method所指向的就是前面委托定义的method     更多教学视频和资料下载,欢迎关注以下信息: 我的优 ...

  7. 理解进程调度时机跟踪分析进程调度与进程切换的过程(Linux)

    ----------------------------------------------------------------------------------- 理解进程调度时机跟踪分析进程调度 ...

  8. Android之新建项目

    最近开始接触Android,实践出真理,接下来实际创建Android应用程序. 1.启动Eclipse,依次选择 " File/New/Project... " 或 " ...

  9. (字符串的处理4.7.22)POJ 3337 Expression Evaluator(解析C风格的字符串)

    /* * POJ_3337.cpp * * Created on: 2013年10月29日 * Author: Administrator */ #include <iostream> # ...

  10. 子查询四(在select子句中使用子查询)

    示例一.查询出每个部门的编号,名称,位置,部门人数,平均工资 SELECT d.deptno,d.dname,d.loc, (SELECT COUNT(empno) FROM emp WHERE em ...