日期:2014-05-18  浏览次数:21179 次

C#+内存映射硬错误
最近练习使用内存映射处理大型文件,当文件比较小的时候没问题,但遇到大型文件,就得分段映射。XP下总是得不到想要的结果,内存占用非常大,系统慢得要死,直到代码运行结束。Win7下发现内存硬错误,写一段理想情况下的代码,请高手帮忙分析一下,是内存泄露还是代码响应不及时,还是其它问题?谢谢。
C# code

long fileSize = 3<<30;//3G 3G/8M=384,3G%8M=0
uint blockBytes = 1<<23;//8M 8M/64K=128,8M%64K=0,64K为系统页分配粒度
long fileOffset = 0;
byte[] temp = new byte[blockBytes];
while(fileSize-fileOffset>0)
{
    IntPtr hMapView = MapViewOfFile(hMapping, FILE_MAP_COPY | FILE_MAP_READ | FILE_MAP_WRITE,
        (uint)(fileOffset >> 32), (uint)(fileOffset & 0xFFFFFFFF), blockBytes);
    if (hMapView == IntPtr.Zero)
    {
        throw new Exception(Marshal.GetLastWin32Error().ToString());
    }
    Marshal.Copy(hMapView, temp, 0, (int)blockBytes);
    fileOffset += blockBytes;
    UnmapViewOfFile(hMapView);
}



------解决方案--------------------
你这个循环不该存在的,既然是分段映射,那么就应该分段显示或使用,你分段映射全一次性全部遍历,这不显然有问题吗?另外你的fileSize太离谱了,根本不用实际文件大小,随便给了一个超大的3G大小,你的文件难道正好那么大?
------解决方案--------------------
fileSize要用API函数GetFileSize去获得,怎么能随便给呢,尺寸乱了,你还能映射正确的位置吗
------解决方案--------------------
循环导致分段映射一次性全部遍历,文件数据被大量读入内存中,然而数据处理跟不上,内存占用非常大,系统变得很慢。
可以考虑用信号量来触发Marshal.Copy()的动作,或用多线程,一读一写,并通知另一线程去处理就可以了。