0

我有一个文件,我在该文件上使用内存映射来创建巨大的数组(可能不适合物理内存)。内存上映射了两个区域 - 数组计数(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 有时会随机产生错误,而且很少发生

4

1 回答 1

0

创建内存映射后释放文件句柄出错。没有过期时间。但是只要内存映射存在,您就应该保留文件句柄。

于 2018-07-20T16:34:17.483 回答