加入收藏 | 设为首页 | 会员中心 | 我要投稿 衡阳站长网 (https://www.0734zz.cn/)- 数据集成、设备管理、备份、数据加密、智能搜索!
当前位置: 首页 > 站长资讯 > 外闻 > 正文

80%的 Linux 运维都不懂的内核问题

发布时间:2018-12-17 14:23:50 所属栏目:外闻 来源:luodw
导读:前言 之前在实习时,听了 OOM 的分享之后,就对 Linux 内核内存管理充满兴趣,但是这块知识非常庞大,没有一定积累,不敢写下,担心误人子弟,所以经过一个一段时间的积累,对内核内存有一定了解之后,记录以及分享。 【OOM - Out of Memory】内存溢出 内

从这个介绍可以看出,当 drop_caches 文件为1时,这时将释放 pagecache 中可释放的部分(有些 cache 是不能通过这个释放的),当 drop_caches 为2时,这时将释放 dentries 和 inodes 缓存,当 drop_caches 为3时,这同时释放上述两项。

关键还有最后一句,意思是说如果 pagecache 中有脏数据时,操作 drop_caches 是不能释放的,必须通过 sync 命令将脏数据刷新到磁盘,才能通过操作 drop_caches 释放 pagecache。

ok,之前有提到有些pagecache是不能通过drop_caches释放的,那么除了上述提文件映射和共享匿名映射外,还有有哪些东西是存在pagecache了?

4.2 tmpfs

我们先来看下 tmpfs ,tmpfs 和 procfs,sysfs 以及 ramfs 一样,都是基于内存的文件系统,tmpfs 和 ramfs 的区别就是 ramfs 的文件基于纯内存的,和 tmpfs 除了纯内存外,还会使用 swap 交换空间,以及 ramfs 可能会把内存耗尽,而 tmpfs 可以限定使用内存大小,可以用命令 df -T -h 查看系统一些文件系统,其中就有一些是 tmpfs,比较出名的是目录 /dev/shm

tmpfs 文件系统源文件在内核源码 mm/shmem.c,tmpfs实现很复杂,之前有介绍虚拟文件系统,基于 tmpfs 文件系统创建文件和其他基于磁盘的文件系统一样,也会有 inode,super_block,identry,file 等结构,区别主要是在读写上,因为读写才涉及到文件的载体是内存还是磁盘。

而 tmpfs 文件的读函数 shmem_file_read,过程主要为通过 inode 结构找到 address_space 地址空间,其实就是磁盘文件的 pagecache,然后通过读偏移定位cache 页以及页内偏移。

这时就可以直接从这个 pagecache 通过函数 __copy_to_user 将缓存页内数据拷贝到用户空间,当我们要读物的数据不pagecache中时,这时要判断是否在 swap 中,如果在则先将内存页 swap in,再读取。

tmpfs 文件的写函数 shmem_file_write,过程主要为先判断要写的页是否在内存中,如果在,则直接将用户态数据通过函数__copy_from_user拷贝至内核pagecache中覆盖老数据,并标为 dirty。

如果要写的数据不再内存中,则判断是否在swap 中,如果在,则先读取出来,用新数据覆盖老数据并标为脏,如果即不在内存也不在磁盘,则新生成一个 pagecache 存储用户数据。

由上面分析,我们知道基于 tmpfs 的文件也是使用 cache 的,我们可以在/dev/shm上创建一个文件来检测下:

80%的 Linux 运维都不懂的内核问题

看到了吧,cache 增长了1G,验证了 tmpfs 的确使用的 cache 内存。

其实 mmap 匿名映射原理也是用了 tmpfs,在 mm/mmap.c->do_mmap_pgoff 函数内部,有判断如果 file 结构为空以及为 SHARED 映射,则调用 shmem_zero_setup(vma) 函数在 tmpfs 上用新建一个文件

80%的 Linux 运维都不懂的内核问题

这里就解释了为什么共享匿名映射内存初始化为0了,但是我们知道用 mmap 分配的内存初始化为0,就是说 mmap 私有匿名映射也为0,那么体现在哪了?

这个在 do_mmap_pgoff 函数内部可没有体现出来,而是在缺页异常,然后分配一种特殊的初始化为0的页。

那么这个 tmpfs 占有的内存页可以回收吗?

80%的 Linux 运维都不懂的内核问题

也就是说 tmpfs 文件占有的 pagecache 是不能回收的,道理也很明显,因为有文件引用这些页,就不能回收。

4.3 共享内存

posix 共享内存其实和 mmap 共享映射是同一个道理,都是利用在 tmpfs 文件系统上新建一个文件,然后再映射到用户态,最后两个进程操作同一个物理内存,那么 System V 共享内存是否也是利用 tmpfs 文件系统了?

我们可以跟踪到下述函数

80%的 Linux 运维都不懂的内核问题

这个函数就是新建一个共享内存段,其中函数

  1. shmem_kernel_file_setup 

(编辑:衡阳站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读