我有一个文件,我使用内存映射来创建大型数组(可能不适合物理内存)。在内存上映射了两个区域 - 数组计数(4个字节)和一些在文件上移动以访问不同数组元素的窗口。
除非有一个问题,否则一切正常。在使用数组计数进行多次多次操作(有时数百万次操作)之后 - 当我尝试通过其内存地址读取或写入此计数时,我得到系统消息“拒绝访问”,该内存地址自创建以来从未改变。
看起来这个映射页面以某种方式到期......
type // view info TViewInfo = record ptr: pointer; // pointer to fist byte in view offset: longword; // offset of our data inside the view addr: PPointer; // pointer to variable pointer (ptr + offset) end; TSizeRec = packed record case integer of 0: (full: int64); 1: (lo, hi: longword); end; function TFileMappedArray.CreateView(offset: int64; size: longword; var p: pointer): TViewInfo; var offs: TSizeRec; fsize: int64; begin p := nil; result.addr := @p; // view must start on the mem_granularity*N offset // so we need to adjust our numbers result.offset := offset mod fMemGranularity; offs.full := (offset div fMemGranularity)*fMemGranularity; size := size + result.offset; fsize := int64(fMaxNumOfItems)*fItemSize + sizeof(longword); if (offs.full fsize) then size := fsize - offs.full; result.ptr := MapViewOfFile(fMappingHandle, FILE_MAP_WRITE, offs.hi, offs.lo, size); p := pointer(longword(result.ptr) + result.offset); end; var fNumberOfItems: PLongword; // our counter fNumberView: TViewInfo; // our view // create view of first 4 bytes in file fNumberView := CreateView(0, 4, pointer(fNumberOfItems)); // get count array count := fNuberOfItems^; // set count fNumberOfItems^ := new count;
获取或设置计数有时产生错误,随机且很少
答案 0 :(得分:0)
创建内存映射后释放文件句柄时出错。随时间没有过期。但是,只要存在内存映射,就应该保持文件句柄。