我有一个文件,我在该文件上使用内存映射来创建巨大的数组(可能不适合物理内存)。内存上映射了两个区域 - 数组计数(4 个字节)和一些正在文件上移动以访问数组的不同元素的窗口。
一切正常,除非一个问题。在对数组计数进行多次操作(有时是数百万次操作)之后 - 当我尝试通过其内存地址读取或写入此计数时,我收到系统消息“访问被拒绝”,该地址自创建以来从未改变。
看起来这个映射页面以某种方式过期......
类型 // 查看信息 TViewInfo = 记录 ptr:指针;// 指向视图中第一个字节的指针 偏移量:长字;// 我们的数据在视图中的偏移量 地址:PPointer;// 指向变量指针的指针 (ptr + offset) 结尾; TSizeRec = 打包记录 案例整数 0:(完整:int64); 1:(lo,hi:长字); 结尾; 函数 TFileMappedArray.CreateView(offset: int64; size: longword; var p: 指针): TViewInfo; 变量 关闭:TSizeRec; fsize:int64; 开始 p := 无; 结果.addr := @p; // 视图必须从 mem_granularity*N 偏移开始 // 所以我们需要调整我们的数字 result.offset := offset mod fMemGranularity; offs.full := (offset div fMemGranularity)*fMemGranularity; 尺寸 := 尺寸 + 结果偏移量; fsize := int64(fMaxNumOfItems)*fItemSize + sizeof(longword); 如果(offs.full fsize)那么 尺寸:= fsize - offs.full; result.ptr := MapViewOfFile(fMappingHandle, FILE_MAP_WRITE, offs.hi, offs.lo, size); p := 指针(longword(result.ptr) + result.offset); 结尾; 变量 fNumberOfItems:PLongword;// 我们的计数器 fNumberView:TViewInfo;// 我们的观点 // 创建文件前 4 个字节的视图 fNumberView := CreateView(0, 4, 指针(fNumberOfItems)); // 获取计数 数组计数:= fNuberOfItems^; // 设置计数 fNumberOfItems^ := 新计数;
get 或 set count 有时会随机产生错误,而且很少发生