C# 内存映射文件和内存消耗
给定以下测试代码(x64环境): 鉴于“d:\map”是一个40GB的文件,当通过指针“ptr”进行随机访问时,会出现一种非常奇怪的行为 系统物理内存得到充分利用,一切都变慢了,这个过程需要2个多小时才能完成 当我进行顺序(和单线程)访问时,使用的物理内存不会超过1GB,整个过程大约需要8分钟 我的问题是:当使用内存映射文件时,“真实”内存会被使用吗?不仅仅是虚拟地址空间被占用了吗C# 内存映射文件和内存消耗,c#,memory-mapped-files,C#,Memory Mapped Files,给定以下测试代码(x64环境): 鉴于“d:\map”是一个40GB的文件,当通过指针“ptr”进行随机访问时,会出现一种非常奇怪的行为 系统物理内存得到充分利用,一切都变慢了,这个过程需要2个多小时才能完成 当我进行顺序(和单线程)访问时,使用的物理内存不会超过1GB,整个过程大约需要8分钟 我的问题是:当使用内存映射文件时,“真实”内存会被使用吗?不仅仅是虚拟地址空间被占用了吗 我试图理解使用内存映射文件时的物理内存消耗。内存映射文件使用虚拟内存。与64位操作系统上的RAM相比,映射更多GB
我试图理解使用内存映射文件时的物理内存消耗。内存映射文件使用虚拟内存。与64位操作系统上的RAM相比,映射更多GB的VM空间不会有问题。在按需页虚拟内存操作系统中,所有运行进程所需的内存总和总是大大超过RAM的数量 将其映射到RAM需要花费金钱,这就是需求发挥作用的地方。当处理器试图访问未映射到RAM的虚拟内存地址时,会中断程序并大声呼救。称为页面错误 如果你没有花那么多钱获得至少40GB的RAM,那么你将不可避免地支付操作系统处理这些页面错误的费用。这需要分配一个RAM页面并用文件中的内容填充它。当Perf必须取消映射之前映射的RAM并将其内容保存到文件时,Perf将南下。然后重新使用释放的RAM页面,并从适当的文件偏移量加载文件内容。非常慢,磁盘速度很慢。一个被称为“鞭打”的问题
当您按顺序寻址内存时,问题就小得多了,一个页面错误适用于4096字节的顺序访问,当您出现页面错误时,您很有可能磁盘读卡器磁头仍然位于正确的位置。我可以将非常大的1-2Gb文件映射到进程,并且该内存将从虚拟内存中获取,这对吗?但无论如何,这是否意味着我的进程将消耗1-2GB的内存?
static void Test()
{
string fileName = @"d:\map";
long length = new FileInfo(fileName).Length;
using (var file = MemoryMappedFile.CreateFromFile(fileName, FileMode.Open, "mapFile", length, MemoryMappedFileAccess.ReadWrite))
{
byte* bytePtr = (byte*)0;
var view = file.CreateViewAccessor(0, length, MemoryMappedFileAccess.ReadWrite);
view.SafeMemoryMappedViewHandle.AcquirePointer(ref bytePtr);
long count = (long)(length / sizeof(int));
long sum = 0;
long step = count / 2000;
int* ptr = (int*)&bytePtr[0];
long currentCount = 0 ;
Parallel.For(0, count, new ParallelOptions { MaxDegreeOfParallelism = 8 }, (i) =>
{
Interlocked.Add(ref sum, ptr[i]);
Interlocked.Increment(ref currentCount) ;
if (currentCount % step == 0)
Console.Write("\r{0:0.00}%", (100 * currentCount / (float)count));
});
Console.WriteLine(sum);
view.Dispose();
}
}