在为我的 Linux 机器添加更多内存后,我想更积极地使用缓存。
事情是这样的:我启动我的机器,去洗手间,回来登录。大约需要半分钟才能登录。然后我启动 Firefox,又需要一些时间。当我注销并重新登录时,所有这些事情都会在几秒钟内发生,因为那时缓存是热的。所以我想:当我在浴室时,如何教我的机器将所有这些文件放入缓存中。
我研究了预加载,发现结果有些令人失望。其最终原因似乎是它只跟踪 mmap()ed 文件,而不跟踪通过 read() 读取的文件。
我怀疑这是因为 mmap()ed 文件更容易观察。当应用程序 mmap()sa 文件时,它会在内存中保留一段时间,而 open()-read()-close() 可能会在不到一秒的时间内发生(如果我错了,请纠正我)。
似乎没有一种简单的方法可以在读取文件时收到通知。有inotifiy,但它需要正确注册目录和IIRC,并不意味着监视整个文件系统。
理想情况下,我希望在 /dev 中有一个设备(如 tty),我可以从中读取某些应用程序从中读取的文件名。
(1) 有类似的东西吗?
(2) 有什么原因导致这很困难吗?
如果我有有关读取文件访问的信息,我可以在启动期间轻松预热缓存。
答案1
read
关于系统调用的缓存:
系统read
调用可以应用于大量套接字类型。所以它本身没有缓存逻辑read
。但是,如果您在文件系统上进行 IO 操作,文件系统本身可能支持缓存技术,但这取决于您的文件系统。
这与 不同mmap
,因为mmap
它是专门为将大文件映射到内存中并对其进行操作而设计的。如果您这样做,可能值得考虑使用mmap
而不是read
.
关于您帖子的第二部分,您说您希望通过某种方式获取已定义的应用程序或进程正在读取的文件列表:
我不知道如何在/dev
.但是通过使用 System Tap,应该很容易创建一个内核模块,该模块将定义的进程正在执行的所有参数read
或系统调用打印到 dmesg 中。open
然后,您可以向此输出添加诸如预定义前缀之类的内容,因此,如果您这样做,dmesg | grep <prefix>
您将从该内核模块获取所有输出,就像您描述的那样,您希望从/dev
设备获得它。
请注意,这不应该在生产中使用,而只能用于调试或其他非生产目的。
这是关于 System Tap 基础知识的一个很好的指南,学习后您应该能够创建一个仅需要可执行文件的名称或进程的 PID 作为输入的 System Tap 脚本。然后,这可以将来自某个进程或应用程序的所有调用read
或系统调用的参数打印open
到 dmesg 中: