1、命令
echo 1 > /proc/sys/vm/drop_caches
释放文件的page cache内存,对应着top下的cached值
2、cached具体被哪些模块使用着(cat /proc/meminfo)
【Active(file) + Inactive(file) + Shmem + mlock_file】== 【Cached + Buffers】
Active(file)和Inactive(file)对应着文件映射
Shmem对应着内存文件系统,如/tmp;或者mmap的映射
addr = mmap(, , , MAP_ANONYMOUS|MAP_SHARED, , );
其中Shmem占着的空间是没有办法通过echo 1 > /proc/sys/vm/drop_caches释放的
3、Active(file)和Inactive(file)的空间具体被哪些文件使用着
这两块的空间可以通过echo 1 > /proc/sys/vm/drop_caches来回收释放,可以通过drop_caches的处理发现端倪。
3.1、查看内核代码/kernel/sysctl.c的vm_table结构体,发现
static struct ctl_table vm_table[] = {
......
{
.procname = "drop_caches",
.data = &sysctl_drop_caches,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = drop_caches_sysctl_handler,
.extra1 = &one,
.extra2 = &four,
},
......
};
int drop_caches_sysctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos)
{
int ret;
......
if (write) {
static int stfu;
if (sysctl_drop_caches & 1) {
iterate_supers(drop_pagecache_sb, NULL);
count_vm_event(DROP_PAGECACHE);
}
......
}
return 0;
}
//fs/super.c
//list_for_each_entry遍历所有的文件系统
void iterate_supers(void (*f)(struct super_block *, void *), void *arg)
{
......
list_for_each_entry(sb, &super_blocks, s_list) {
......
if (sb->s_root && (sb->s_flags & SB_BORN))
f(sb, arg);
......
}
}
//fs/drop_caches.c
//list_for_each_entry遍历此文件系统下的所有文件inode
static void drop_pagecache_sb(struct super_block *sb, void *unused)
{
......
list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
......
invalidate_mapping_pages(inode->i_mapping, 0, -1);
......
}
}
先遍历文件系统类型,然后遍历文件系统下所有的文件inode(在获取inode的情况下,参考通过inode获取文件名信息_sydyh43的博客-CSDN博客就可以获取文件名信息),再判断inode成员i_mapping指向的page的属性
int invalidate_inode_page(struct page *page)
{
struct address_space *mapping = page_mapping(page);
if (!mapping)
return 0;
if (PageDirty(page) || PageWriteback(page))
return 0;
if (page_mapped(page))
return 0;
return invalidate_complete_page(mapping, page);
}
从函数invalidate_inode_page中可以看出,当page是dirty, writeback等属性时,不做cache回收