Page Cache(页缓存)
Page Cache
- 由内存中的物理page组成,其内容对应磁盘上的block。
- page cache的大小是动态变化的。
- backing store: cache缓存的存储设备
- 一个page通常包含多个block, 而block不一定是连续的。
读Cache
当内核发起一个读请求时, 先会检查请求的数据是否缓存到了page cache中。
- 如果有,那么直接从内存中读取,不需要访问磁盘, 此即 cache hit(缓存命中)
- 如果没有, 就必须从磁盘中读取数据, 然后内核将读取的数据再缓存到cache中, 如此后续的读请求就可以命中缓存了。
page可以值缓存一个文件的部分内容, 而不需要吧整个文件都缓存进来。
写Cache
- 当内核发起一个写请求时, 也是直接往cache中写入, 后备存储中的内容不会直接更新。
- 内核会将被写入的page标记为dirty, 并将其加入到dirty list中。
- 内核会周期性地将dirty list中的page写回到磁盘上, 从而使磁盘上的数据和内存中缓存的数据一致。
Cache回收
- Page cache的另一个重要工作是释放page, 从而释放内存空间。
- cache回收的任务是选择合适的page释放
- 如果page是dirty的, 需要将page写回到磁盘中再释放。
LRU算法
- LRU(Least Recently used): 最近最少使用算法, Redis中也有此策略, 该算法在Java中可以使用LinkedHashMap进行实现。
Two-List策略
- Two-List策略维护了两个list: active list && inactive list
- 在active list上的page被认为是hot的,不能释放。
- 只有inactive list上的page可以被释放的。
- 首次缓存的数据的page会被加入到inactive list中,已经在inactive list中的page如果再次被访问,就会移入active list中。
- 两个链表都使用了伪LRU算法维护,新的page从尾部加入,移除时从头部移除
- 如果active list中page的数量远大于inactive list,那么active list头部的页面会被移入inactive list中,从而实现两个表的平衡。
Linux中Page Cache的具体实现
address_space
struct address_space {
struct inode *host; /* owning inode */
struct radix_tree_root page_tree; /* radix tree of all pages */
spinlock_t tree_lock; /* page_tree lock */
unsigned int i_mmap_writable; /* VM_SHARED ma count */
struct prio_tree_root i_mmap; /* list of all mappings */
struct list_head i_mmap_nonlinear; /* VM_NONLINEAR ma list */
spinlock_t i_mmap_lock; /* i_mmap lock */
atomic_t truncate_count; /* truncate re count */
unsigned long nrpages; /* total number of pages */
pgoff_t writeback_index; /* writeback start offset */
struct address_space_operations *a_ops; /* operations table */
unsigned long flags; /* gfp_mask and error flags */
struct backing_dev_info *backing_dev_info; /* read-ahead information */
spinlock_t private_lock; /* private lock */
struct list_head private_list; /* private list */
struct address_space *assoc_mapping; /* associated buffers */
};- 其中 host域指向对应的inode对象,host有可能为NULL,这意味着这个address_space不是和一个文件关联,而是和swap area相关,swap是Linux中将匿名内存(比如进程的堆、栈等,没有一个文件作为back store)置换到swap area(比如swap分区)从而释放物理内存的一种机制。page_tree保存了该page cache中所有的page,使用基数树(radix Tree)来存储。i_mmap是保存了所有映射到当前page cache(物理的)的虚拟内存区域(VMA)。nrpages是当前address_space中page的数量。
address_space操作函数
- address_space中的a_ops域指向操作函数表(struct address_space_operations),每个后备存储都要实现这个函数表。
内核使用函数表中的函数管理page cache,其中最重要的两个函数是readpage() 和writepage()
- readpage()函数
- readpage()首先会调用find_get_page(mapping, index)在page cache中寻找请求的数据
- mapping是要寻找的page cache对象,即address_space对象
- index是要读取的数据在文件中的偏移量
- 如果请求的数据不在该page cache中,那么内核就会创建一个新的page加入page cache中,并将要请求的磁盘数据缓存到该page中,同时将page返回给调用者。
- writepage()函数
- 对于文件映射, page每次修改后都会调用SetPageDirty(page)将page标识为dirty。
- 内核首先在指定的address_space寻找目标page
- 如果没有,就分配一个page并加入到page cache中,然后内核发起一个写请求将数据从用户空间拷入内核空间,最后将数据写入磁盘中。
- readpage()函数
Buffer Cache
用于表示内存到磁盘映射的buffer_head结构
每个buffer-block映射都有一个buffer_head结构,buffer_head中的b_assoc_map指向了address_space。
值得注意的是在Linux2.4中,buffer cache和 page cache之间是独立的
- 前者使用老版本的buffer_head进行存储,这导致了一个磁盘block可能在两个cache中同时存在,造成了内存的浪费。
- 2.6内核中将两者合并到了一起,使buffer_head只存储buffer-block的映射信息,不再存储block的内容, 从而减少了内存浪费。
Flusher Threads
- Page Cache推迟了文件写入后备存储的时间, 但是dirty page最终还是要被写回磁盘的。
- 内核会在以下三种情况下将dirty page 写回磁盘:
- 用户进程调用sync() 和 fsync()系统调用
- 空闲内存低于特定的阈值(threshold)
- Dirty数据在内存中驻留的时间超过一个特定的阈值
- 线程群的特点是让一个线程负责一个存储设备(比如一个磁盘驱动器),多少个存储设备就用多少个线程, 从而避免阻塞或者竞争的情况,提高效率。
- 当空闲内存低于阈值时,内核就会调用wakeup_flusher_threads()来唤醒一个或者多个flusher线程,将数据写回磁盘。
- 为了避免dirty数据在内存中驻留过长时间(避免在系统崩溃时丢失过多数据),内核会定期唤醒一个flusher线程,将驻留时间过长的dirty数据写回磁盘。
Page Cache(页缓存)的更多相关文章
- System.Web.UI.Page.Cache 页面 缓存 清除
这个也是网上查询到方法,不错记录一下! /// <summary> /// 清空所有的Cache /// </summary> public static void Clear ...
- Linux系统中的Page cache和Buffer cache
Linux系统中的Page cache和Buffer cache Linux中有两个很容易混淆的概念,pagecache和buffercache,首先简单将一些Linux系统下内存的分布,使用free ...
- page cache 与free
我们经常用free查看服务器的内存使用情况,而free中的输出却有些让人困惑,如下: 先看看各个数字的意义以及如何计算得到: free命令输出的第二行(Mem):这行分别显示了物理内存的总量(tota ...
- Linux内核入门到放弃-页缓存和块缓存-《深入Linux内核架构》笔记
内核为块设备提供了两种通用的缓存方案. 页缓存(page cache) 块缓存(buffer cache) 页缓存的结构 在页缓存中搜索一页所花费的时间必须最小化,以确保缓存失效的代价尽可能低廉,因为 ...
- 从free到page cache
Free 我们经常用free查看服务器的内存使用情况,而free中的输出却有些让人困惑,如下: 图1-1 先看看各个数字的意义以及如何计算得到: free命令输出的第二行(Mem):这行分别显示了 ...
- linux 中的页缓存和文件 IO
本文所述是针对 linux 引入了虚拟内存管理机制以后所涉及的知识点.linux 中页缓存的本质就是对于磁盘中的部分数据在内存中保留一定的副本,使得应用程序能够快速的读取到磁盘中相应的数据,并实现不同 ...
- 工作于内存和文件之间的页缓存, Page Cache, the Affair Between Memory and Files
原文作者:Gustavo Duarte 原文地址:http://duartes.org/gustavo/blog/post/what-your-computer-does-while-you-wait ...
- Page Cache, the Affair Between Memory and Files.页面缓存-内存与文件的那些事
原文标题:Page Cache, the Affair Between Memory and Files 原文地址:http://duartes.org/gustavo/blog/ [注:本人水平有限 ...
- 在page cache中的页,如果当时没有进程read或者write,引用计数到底该为多少
在一次偶然的机会,在研究如何降低pagecache占用的过程中,走查了 invalidate_mapping_pages的代码: 通过调用 __pagevec_lookup 在radix树中收集一部分 ...
随机推荐
- vue环境搭建及单页面标签切换实例
复习 """ 1.指令: v-once: <p v-once>{{ msg }}</p> v-cloak: 防止页面加载抖动 v-show:绑定的 ...
- Codeforces Round #624 (Div. 3) A. Add Odd or Subtract Even(水题)
You are given two positive integers aa and bb . In one move, you can change aa in the following way: ...
- Git - 01. git config
1. 概述 管理 git 配置文件命令 配置算是 git 的 meta 大概了解下就行 写这个的原因, 是因为 安装 的时候需要配置 用户名 和 密码 这个操作本质上, 是对属性的配置 先简单知道下操 ...
- P&R 3
Floorplan: 要做好floorplan需要掌握哪些知识跟技能? 通常,遇到floorplan问题,大致的debug步骤跟方法有哪些? 如何衡量floorplan的QA? Floorplan是后 ...
- <好きになるなら> 歌詞
あー生意気なこと言ったあと 何故かしらぽつんとしてしまう あー偶然のふり待ちぶせた ゴメンネと素直に言えるかな 帰る道はいつもカナリア 変ねこのごろ自分の気持ちがよめない もうじき風の向きが変わりそう ...
- HDU 6631 line symmetric 计算几何
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6631 题意:共\(T\)组数据,每组数据给出\(n\)个点的坐标,这\(n\)个点按顺序给出,相邻的点 ...
- 去除移动端苹果手机(ios)的input默认样式与input禁止键盘出现的方式
样式: input{-webkit-appearance: none;} 在iPhone plus点击input框出生日期时会出现如下图: 为了去掉下面那条苹果自带的,可以这样处理:在HTML中的in ...
- 【转】直播流程,视频推流,视频拉流,简介,SMTP、RTMP、HLS、 PLPlayerKit
原:https://www.cnblogs.com/baitongtong/p/11248966.html 1 .音视频处理的一般流程: 数据采集→数据编码→数据传输(流媒体服务器) →解码数据→播放 ...
- dfs+枚举,flip游戏的拓展POJ2965
POJ 2965 The Pilots Brothers' refrigerator Description The game “The Pilots Brothers: fo ...
- SpringMVC Controller 接收页面传递的中文参数出现乱码
在Controller中接收到的POST参数如果是中文的话,显示为乱码.已知客户端传过来时编码为UTF-8. 问题产生分析: spring MVC中默认的编码格式为“ISO-8859-1”,因此造成乱 ...