在现代Windows系统上打开文件需要多少内存?某些应用程序加载需要打开“大量”文件。 Windows能够打开“大量”文件,但是保持单个文件打开的负担是什么,以便人们可以决定“很多”是“太多”?
对于32位进程内的大型数据集(100s MB~几GB)的顺序处理,我们需要提供一个缓冲区,将其内容存储在磁盘而不是内存中。
我们在没有太多问题的情况下充实了一个小课程(使用CreateFile
FILE_ATTRIBUTE_TEMPORARY
和FILE_FLAG_DELETE_ON_CLOSE
)。
问题是,这些缓冲区的使用方式是每个缓冲区(每个临时文件)可以存储几个字节到几GB的数据,我们希望将缓冲区类本身保存为最小化,尽可能一般。
用例范围从100个缓冲区(每个缓冲区大约100MB)到100.000s缓冲区(每个缓冲区只有几个字节)。 (是的,重要的是这个意义上的每个缓冲区都有它自己的文件。)
在缓冲区类中包含一个缓冲区阈值似乎很自然,当缓冲区类实际存储的字节多于创建+引用临时文件时使用的(内存)开销时,它只开始创建和使用临时磁盘文件 - 在进程中以及在物理机器内存上加载。
在现代Windows系统上打开(临时)文件需要多少内存(以字节为单位)?
CreateFile
与FILE_ATTRIBUTE_TEMPORARY
和FILE_FLAG_DELETE_ON_CLOSE
也就是说,当您开始在文件中而不是在内存中存储数据时,看到净主内存增益(进程内和物理上)的阈值(以字节为单位)是什么?
提及的评论open file limit不适用于CreateFile
,仅适用于MS CRT文件API。 (通过CreateFile打开10.00s文件在我的系统上完全没问题 - 这是一个好主意是不是完全不同而且不是这个问题的一部分。
内存映射文件:完全不适合在32位进程中处理GB数据,因为您无法将这些大型数据集可靠地映射到32位进程的正常2GB地址范围。 < em>完全对我的问题毫无用处,并且完全不以任何方式与实际问题相关。普通文件适合背景问题。
查看http://blogs.technet.com/b/markrussinovich/archive/2009/09/29/3283844.aspx - 它告诉我{64}系统上HANDLE
本身占用16个字节,但只是句柄。
查看了STXXL和它的文档,但是这个lib也不适用于我的任务,在开始实际使用文件之前,我没有发现任何有用的阈值。
Raymond writes:“答案会因安装的防病毒软件而异,因此唯一可以知道的是在生产配置上对其进行测试。”
qwm writes:“我会更关心cpu开销。无论如何,回答问题的最好方法是测试它。我只能说_FILE_OBJECT
的大小单独(包括_OBJECT_HEADER
)是~300b,其中一些字段是指向其他相关结构的指针。“
Damon wri tes:“一个正确的答案是:10个字节(在我的Windows 7机器上)。由于没有其他人似乎值得尝试,我做了(测量差异)在MEMORYSTATUSEX::ullAvailVirtual
超过100k的调用,没有其他运行)。不要问我为什么它不是8或16字节,我不知道。大约17秒的内核时间,进程有100,030个句柄打开私有工作集在运行期间上升了412k,而全局可用VM下降了1M,因此大约60%的内存开销在内核中。(...)“
“更令人震惊的是,CreateFile
明显消耗了大量的内核时间(繁忙的CPU时间,而不是在磁盘上等待!)。对于100k呼叫,17秒就可以归结为大约450,000个周期在这台机器上打开一个手柄。相比之下,仅仅10个字节的虚拟内存就可以忽略不计了。“
答案 0 :(得分:5)
我现在做了一些测量:
创建一个临时文件的调用(我保持它的句柄直到结束)看起来像这样:
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免费)。