0%

Linux Page Cache&Swap Cache

Struct address_space

1
2
3
4
5
6
7
struct page {
unsigned long flags
union {
struct {
struct list_head lru;
struct address_space *mapping;
......
  • 在结构体 page 中有一个特殊的成员 mapping,指向地址空间描述的结构指针
  • 结构体 file 和结构体 inode 中都有一个结构体 address_space 指针(file->f_mapping 是由 inode->i_mapping 初始化而来)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
struct address_space {
struct inode *host; /* 拥有此address_space的inode对象 */
struct xarray i_pages; /* 缓存的页面(一种抽象的数据类型,其行为类似于一个非常大的指针数组) */
gfp_t gfp_mask; /* 用于分配页的内存分配标志 */
atomic_t i_mmap_writable; /* VM_SHARED计数 */
struct rb_root_cached i_mmap; /* 私有映射链表的树 */
struct rw_semaphore i_mmap_rwsem; /* 读写信号量 */
unsigned long nrpages; /* 总页数 */
unsigned long nrexceptional; /* Shadow or DAX条目,受i_pages锁保护 */
pgoff_t writeback_index; /* 回写的起始偏移 */
const struct address_space_operations *a_ops; /* address_space的操作表 */
unsigned long flags; /* gfp_mask掩码与错误标识 */
errseq_t wb_err;
spinlock_t private_lock; /* 私有address_space自旋锁 */
struct list_head private_list; /* 私有address_space链表 */
void *private_data; /* 私有数据指针 */
} __attribute__((aligned(sizeof(long)))) __randomize_layout;
  • 结构 address_space->i_pages 的作用就是用于存储文件的 Page Cache
  • 一个 address_space 与一个偏移量能够确定一个 page cacheswap cache 中的一个页面

Page Cache

所以为了避免每次读写文件时,都需要对硬盘进行读写操作,Linux 内核使用页缓存(Page Cache)机制来对文件中的数据进行缓存

  • Page Cache 是与文件映射对应的
  • 用户对文件的读写会先操作 Page Cache,如果找不到对应的 Page Cache 就会申请一个
  • 修改的页缓存 Page Cache 被称为脏页,内核会定时把这些脏页刷新到文件中

如果进程需要 pagefree page 严重短缺的时候,进程可以唤醒这些内核线程来回收缓存的页面,一方面缓存,一方面回收达到一种平衡,同时改善了系统的性能

Swap

在 Linux 下,当物理内存不足时,拿出部分硬盘空间当 Swap 分区(也被称为“虚拟内存”,从硬盘中划分出的一个分区),从而解决内存容量不足的情况

  • Swap 意思是交换, 当物理内存不够用的时候,内核就会释放缓存区(buffers/cache)里一些长时间不用的程序,然后将这些程序临时放到 Swap 中
  • Swap Out:当某进程向OS请求内存发现不足时,OS会把内存中暂时不用的数据交换出去,放在 SWAP 分区中
  • Swap In:当某进程又需要这些数据且OS发现还有空闲物理内存时,又会把 Swap 分区中的数据交换回物理内存中

Swap Cache

Swap Cache 就是 Swap 的缓存,它的作用不是说要加快磁盘的I/O效率

  • Swap Cache 是与匿名页对应的
  • 匿名页是没有关联任何文件的 page,比如用户进程通过 malloc 申请的内存页(函数 mmap 也可以申请匿名页)

Swap Cache 主要是为了防止页面在 Swap In 和 Swap Out 时进程的同步问题

  • 如果页面的数据还没有完全写入磁盘时,这个 page frame 是在 swap cache
  • 等数据完全写入磁盘后,而且没有进程对 page frame 进行访问,那么 swap cache 才会释放 page frame,将其交给 buddy system
  • 匿名页即将被 Swap Out 时会先被放进 Swap Cache,但通常只存在很短暂的时间,因为紧接着在该 page 完全放入磁盘之后它就会从 Swap Cache 中删除(毕竟 Swap Out 的目的就是为了腾出空闲内存)