tl; dr
打开文件在现代Windows系统上会有多少内存?某些应用程序负载将需要打开"很多"文件。Windows非常有能力打开"很多"文件,但是保持单个文件打开的负载是什么,以便可以决定何时"很多"是"太多"?
背景
用于在32位进程中的大型数据集(100s Mb〜几个GB)的顺序处理,我们需要提出一个缓冲区,该缓冲区将其内容存储在磁盘上而不是在内存中。
我们已经充实了一个小课,没有太多问题(将CreateFile
与FILE_ATTRIBUTE_TEMPORARY
和FILE_FLAG_DELETE_ON_CLOSE
一起使用)。
问题是,这些缓冲区的使用方式是,每个缓冲区(每个临时文件)可能会从几个字节中存储到最多几个GB数据,我们希望将缓冲区类本身保持为最小和一般。
用例范围从100个缓冲区,每个缓冲区〜100MB到100.000秒的缓冲区,每个缓冲区只有几个字节。(是的,重要的是,每个缓冲区都有自己的文件。)
在缓冲区类中包含一个缓冲区阈值似乎很自然,该类别仅在实际存储字节时才开始创建和使用临时的磁盘文件,而不是(内存)创建 引用临时文件使用的(内存)开销 - 在过程以及物理机器内存上的加载。
问题
在字节中,打开(临时)文件在现代Windows系统上是否有多少内存?
- 与
FILE_ATTRIBUTE_TEMPORARY
和FILE_FLAG_DELETE_ON_CLOSE
一起使用CreateFile
- (32位)进程的虚拟地址空间的字节打开文件
- 机器上物理内存的字节(包括任何内核数据架构)
也就是说,当您从将数据存储在文件中而不是内存?
时,当您开始看到净主机内存增益(既包括在程序内和物理上)时,阈值是什么?注意:
提到的打开文件限制的注释不适用于CreateFile
,仅适用于MS CRT文件API。(通过CreateFile打开10.00个文件在我的系统上根本没有问题 - 这是否是一个完全不同的问题,而不是这个问题的一部分。
内存映射文件:完全不适合在32位进程中处理GB数据,因为您无法可靠地将如此大的数据集映射到32位进程的正常2GB地址范围。是完全对我的问题毫无用处,并且完全没有与实际问题有关。平原文件对于背景问题就可以了。
看http://blogs.technet.com/b/markrussinovich/archive/2009/09/29/29/3283844.44.aspx-告诉我HANDLE
本身在64位的系统上占16个字节,但是那是 Just 手柄。
查看了stxxl及其文档,但此lib既不适合我的任务,也没有发现在开始使用之前使用文件。
有用的评论摘要:
雷蒙德写道:"答案会根据安装了什么防病毒软件而有所不同,因此唯一知道的方法是在生产配置上进行测试。"
QWM写道:"我会更关心CPU开销。无论如何,回答您的问题的最佳方法是测试它。我只能说仅_FILE_OBJECT
的大小(包括_OBJECT_HEADER
)是〜300B它的字段是其他相关结构的指针。"
damon写道:"一个正确的答案是:10个字节(在我的Windows 7机器上)。由于没有其他人值得实际尝试,所以我做到了(MEMORYSTATUSEX::ullAvailVirtual
的差异在100K呼叫中进行了测量,没有其他运行)。问我为什么不是8或16个字节,我不知道。大约需要17秒的内核时间,流程在退出时开放了100,030个手柄。在运行过程中,私人工作设置在运行期间增加了412K,而全局可用的VM则下降了到1m,大约60%的内存开销位于内核内。(...)"
"更令人惊叹的是大量的内核时间(CPU时间忙,而不是等待磁盘!),CreateFile
显然消耗了。17秒的17秒钟100k呼叫沸腾到约450,000个周期,以打开一个手柄。这台机器。与此相比,仅10个字节的虚拟内存都可以忽略不计。"
我现在进行了一些测量:
- 我设置了带有2G的RAM磁盘,以免弄乱我的普通NTFS文件表。
- 我在循环中创建了1M文件(1,000,000),并通过Perfmon检查了各种系统性能指标。
创建一个临时文件的调用(我将其保留直到最后)看起来像这样:
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);
}
结果是:
- 再次删除了所有临时文件,RAM磁盘的使用如下:
- 总计2060 m字节
- 使用1063 m字节
- 免费997 m字节
- 比较启动和结束值(与介于两者之间的几个样本)我总结了以下每个打开的平均内存消耗(temp)文件:
- 内存/可用字节 - 大约4K字节每个打开文件降低(此计数器上的抖动:显然,因为此测试持续了10分钟
- 内存/池paged字节 - 大约每个打开文件3K字节
- 内存/池非页面字节 - 大约每个打开文件2,2k字节
- 有趣的是, Process 内存负载并没有以任何重要的方式增加(按过程/工作集跟踪)。
请注意,我还完全没有使用页面文件(因为我希望这台机器具有16GB的RAM,并且在最低点我仍然可以免费使用〜4GB)。