TL; DR
在现代Windows系统上打开文件需要占用多少内存?某些应用程序负载将需要打开“大量”文件。 Windows非常有能力打开“大量”文件,但是保持单个文件打开的负担是什么,以便人们可以确定何时“大量”是“太多”?
背景
为了在32位进程中顺序处理大型数据集(100s MB〜几GB),我们需要提供一个缓冲区,将其内容存储在磁盘上而不是内存中。
我们已经充实了一点类(class),没有太多问题(将CreateFile
与FILE_ATTRIBUTE_TEMPORARY
和FILE_FLAG_DELETE_ON_CLOSE
一起使用)。
问题是,这些缓冲区的使用方式使得每个缓冲区(每个临时文件)都可能存储从几个字节到几GB的数据,并且我们希望将缓冲区类本身保持在最小限度并尽可能一般的尽可能。
用例的范围从100个缓冲区(每个缓冲区约100MB)到100.000s缓冲区(每个缓冲区仅几个字节)。 (是的,从这个意义上讲,每个缓冲区都有自己的文件很重要。)
在缓冲区类中包含一个缓冲区阈值似乎很自然,该缓冲区阈值仅在其实际存储的字节数超过创建和引用临时文件所用(内存)开销的字节数时才开始创建和使用临时磁盘文件。以及物理机内存上的负载。
问题
在现代Windows系统上,打开(临时)文件需要多少字节的内存?
CreateFile
与FILE_ATTRIBUTE_TEMPORARY
和FILE_FLAG_DELETE_ON_CLOSE
一起使用也就是说,当您开始看到通过将数据存储在文件中而不是内存中而获得净主内存 yield (过程中以及物理上)时,阈值(以字节为单位)是多少?
笔记:
提到的open file limit注释不适用于
CreateFile
,仅适用于MS CRT文件API。 (通过CreateFile打开10.00s的文件在我的系统上根本没有问题-是否一个好主意完全是另一回事,而不是这个问题的一部分。内存映射文件:完全不适合在32位进程中处理GB的数据,因为您不能可靠地将如此大的数据集映射到32位进程的正常2GB地址范围内。对于我的问题是完全没有用的,并且根本不与实际问题相关。普通文件仅适合解决背景问题。
看了http://blogs.technet.com/b/markrussinovich/archive/2009/09/29/3283844.aspx-它告诉我
HANDLE
本身在64位系统上占用16个字节,但这仅是句柄。查看了STXXL及其文档,但是此lib既不适合我的任务,也没有在开始实际使用文件之前发现任何有用的阈值。
有用的评论摘要:
Raymond writes:“答案将取决于所安装的防病毒软件的不同,因此唯一的了解方法是在生产配置上对其进行测试。”
qwm writes:“我会更关心cpu开销。无论如何,回答您的问题的最好方法是对其进行测试。我只能说
_FILE_OBJECT
的大小(包括_OBJECT_HEADER
)约为300b,其中某些字段是指向其他相关结构的指针。”Damon wri tes:“一个正确的答案是:10字节(在我的Windows 7机器上)。由于没有其他人似乎值得实际尝试,所以我做了(测得的
MEMORYSTATUSEX::ullAvailVirtual
差异超过10万次调用,其他都没有运行。)我不知道为什么它不是8或16字节,占用了大约17秒的内核时间,退出时进程打开了100,030个句柄,运行期间专用工作集增加了412k,而全局可用VM减少了1M ,因此大约60%的内存开销都在内核内部。(...)““更令人震惊的是
CreateFile
显然消耗了大量的内核时间(这是CPU时间,而不是等待磁盘!)。10万次调用的17秒分解为打开该计算机上一个句柄的时间大约为450,000个周期。相比之下,仅有的10个字节的虚拟内存丢失就可以忽略不计了。”
最佳答案
我现在进行了一些测量:
创建一个临时文件的调用(直到结束时我一直保持它的句柄)如下所示:
HANDLE CreateNewTempFile(LPCTSTR filePath) {
return ::CreateFile(
filePath,
GENERIC_READ | GENERIC_WRITE, // reading and writing
FILE_SHARE_READ, // Note: FILE_FLAG_DELETE_ON_CLOSE will also block readers, unless they specify FILE_SHARE_DELETE
/*Security:*/NULL,
CREATE_NEW, // only create if does not exist
FILE_ATTRIBUTE_TEMPORARY | // optimize access for temporary file
FILE_FLAG_DELETE_ON_CLOSE, // delete once the last handle has been closed
NULL);
}
结果是:
请注意,我还跟踪了分页,并且根本没有使用页面文件(这是我希望的,因为这台机器具有16GB的RAM,最低时我仍有〜4GB的可用空间)。
关于c++ - 在Windows上打开文件的内存开销是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21309852/