ちょっと前にMemoryMappedFileを使うことがあったのですが、「確保したサイズを超えないようにチェック処理を追加しようとしたらどうなる?」ということを思いついたので、サンプルをC#で作成。
var _shareMemory1 = MemoryMappedFile.CreateNew(@"Global\TestShareMem1", 512);
var accessor = _shareMemory1.CreateViewAccessor();
Console.WriteLine($"accessor.Capacity={accessor.Capacity}");
accessor.Dispose();
_shareMemory1.Dispose();
「Capacityには512が入るよね?」と思ってたのですが、表示内容は「accessor.Capacity=4096」???
サイズ指定を4097にすると、「accessor.Capacity=8192」
ページサイズ調整されてるっぽいけど、Referenced codeのサイトでMemoryMappedFile.csの実装内容を確認してもそれらしき実装は見つからず。
となると、Win32APIの仕様を確認することになるので、Cでサンプル作成。
HANDLE hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, NULL,
PAGE_READWRITE, 0, 512, szName);
LPCTSTR pBuf = (LPTSTR)MapViewOfFile(hMapFile,
FILE_MAP_ALL_ACCESS, 0, 0, 512);
MEMORY_BASIC_INFORMATION memInfo;
ZeroMemory(&memInfo, sizeof(memInfo));
SIZE_T size = VirtualQuery(pBuf, &memInfo, sizeof(memInfo));
printf("size=%d.\n", memInfo.RegionSize);
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
※MapViewOfFile()でアクセス可能なメモリのサイズを確認するのはVirtualQuery()だそうで。
これでも「size=4096」なので、Win32API側でページ制御されてるらしい。初めて知った。メモリはケチって使うなということか・・・。