本文主要介绍了一些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. OA系统启动:基础数据,工作流设计

    自从开源OA系统启动:系统概览放 出来后.园友们反馈了一些不错的建议.主要集中在工作流部分.本来是先不考虑工作流部分.这些天的交流和思考.决定把工作流部分作为系统基础结构贯穿整个 系统.所以先考虑了这 ...

  2. 同一页面的两个Iframe获取数据

    首先页面: <td style="width: 50%" valign="top"> <iframe name="xxx" ...

  3. 【ES】elasticsearch学习笔记

    ES学习 1 优势 1.1 简单 1.1.1 相比Solor配置部署等非常简单 1.2 高效 1.2.1 ES使用Netty作为内部RPC框架,Solor使用Jetty 1.3 插件化 1.3.1 E ...

  4. magento upsell from cur_category

    <?php /** * Magento * * NOTICE OF LICENSE * * This source file is subject to the Academic Free Li ...

  5. [Backbone] Parse not formatted JSON code

    The good Dr. recently had another team implement the server and they slightly messed up the format o ...

  6. uva 10721 - Bar Codes(dp)

    题目链接:uva 10721 - Bar Codes 题目大意:给出n,k和m,用k个1~m的数组成n,问有几种组成方法. 解题思路:简单dp,cnt[i][j]表示用i个数组成j, cnt[i][j ...

  7. Hibernate(五)基本数据类型

    一.Hibernate的基本数据类型 3种数据类型之间的对应关系 Hibernate映射类型 Java类型 标准SQL类型 integer java.lang.Integer INTEGER long ...

  8. 应用程序正常初始化(0xc0000135)失败的解决方法

    转自:http://blog.sina.com.cn/s/blog_64fba4e00100mzf9.html 这是由于没有安装.NET framework 所造成的,请安装.NET framewor ...

  9. Linux学习笔记——Ubuntu更新软件源

    0.前言     通过改动ubuntu软件源可提高apt命令下载安装软件的速度.     參考资料     [官方资料]--配置文件改动方法     [Ubuntu如何改动软件源地址]--使用ubun ...

  10. from VC的IDE使用技巧大全

    .cpp是c++源文件 .opt 工程关于开发环境的参数文件.如工具条位置等信息: .aps (AppStudio File),资源辅助文件,二进制格式,一般不用去管他. .clw ClassWiza ...