Caching 磁盘数据的内存缓存

Caching 磁盘数据的内存缓存,caching,memory-management,operating-system,cpu-architecture,Caching,Memory Management,Operating System,Cpu Architecture,我一直都知道主内存会缓存从磁盘上的文件读取的数据,但我很难将其与程序的典型内存使用相协调,如下图所示: 如果我在一个非常大的文件2010Stats.txt上使用fread或fgetl,内存会在上图的哪一段缓存磁盘数据 这是进程的地址空间。每个进程都有自己的虚拟内存地址空间。除非您mmap一个文件,否则当通过read系统调用或等效调用将其复制到进程内存中时,它的数据才会出现在进程内存中。(C stdio/iostream函数将在这样的系统调用之上实现。) 磁盘缓存由操作系统内核管理,它必须跟踪内存

我一直都知道主内存会缓存从磁盘上的文件读取的数据,但我很难将其与程序的典型内存使用相协调,如下图所示:


如果我在一个非常大的文件
2010Stats.txt
上使用
fread
fgetl
,内存会在上图的哪一段缓存磁盘数据

这是进程的地址空间。每个进程都有自己的虚拟内存地址空间。除非您
mmap
一个文件,否则当通过
read
系统调用或等效调用将其复制到进程内存中时,它的数据才会出现在进程内存中。(C stdio/iostream函数将在这样的系统调用之上实现。)


磁盘缓存由操作系统内核管理,它必须跟踪内存的物理页如何使用,以及每个进程的虚拟地址映射。

我认为值得注意的是,当您打开一个文件时,不一定会将其全部内容读入主内存(除非我弄错了)。另外值得注意的是文件句柄,我怀疑它位于进程堆的某个地方——值得注意的是,打开太多文件确实会耗尽内存运行特定进程。@jbowman:在POSIX中,文件描述符只是一个整数。数据都在内核中,内核可以信任它。Windows文件句柄也是如此。stdio
文件*
确实指向堆上进程内部的数据。stdio使用较小的i/o缓冲区来避免对操作系统调用过多的读和写系统调用,我认为这是每一次fopen内存使用的大部分。因此,
myChar=fgetc(myStream)
只消耗程序虚拟地址空间中的1或2个字节,但是存储
2010Stats.txt
myChar
部分的页面大小约为8KB,现在将被放入物理内存中。此页的副本既不在用户程序的虚拟地址空间中,也不在内核中……但它驻留在物理内存中?我可以查找什么操作系统进程或“构造”来了解有关此缓存进程的更多信息?我只是想在我已经熟悉的内存框架中理解它。@Tosh:不要担心内核的虚拟地址空间。例如,Linux使用虚拟地址空间的上1/4映射所有物理内存。(在一个内存超过1G的32位系统上,它不能一次映射所有物理内存:这些页面是HIGHMEM IIRC。)只要假设内核能够很好地使用物理页面,而这些物理页面在其他任何方面都是不需要的。当您调用
mmap
时,它可以将这些页面映射到您的地址空间。当您调用
read
时,它会将这些页面复制到您现有的页面中。@Tosh:没错。页面缓存的全部意义在于它是全局的,由操作系统维护,而不是每个进程的私有缓存。