Windowsアプリで2GB以上のメモリを使うために必要なこと
メモリ4GBマシンがきたので。
実行環境の準備 - boot.iniに/3GBオプションを追加
Windows XPのx86版では、アプリケーションの仮想アドレス空間が2GBに制限されています。4GBのうち半分はカーネルが使うようになっています。このためアプリケーションでは2GB以上のメモリを確保できません。この制限を回避するために、boot.iniに/3GBオプションを追加して、カーネルが3GB以降の1GBしか占有しないようにします。
物理メモリが3.2GBしか認識されない場合など、3GBもアプリケーションに割り当てられない場合は、/Uservaオプションにより2GB〜3GBの間で調節します。
アプリケーション側での対応 - 実行可能ファイルにIMAGE_FILE_LARGE_ADDRESS_AWAREフラグを追加
デフォルトの実行可能ファイルは2GBの仮想アドレス空間しか使えません。この制限を回避するためにIMAGE_FILE_LARGE_ADDRESS_AWAREフラグをヘッダ情報にセットします。このフラグがセットされているアプリケーションは3GBまでの仮想メモリが使えるようなメモリ配置になるようです。
方法としては、
- リンク時に/LARGEADDRESSAWAREオプションを追加
- Editbin.exeで設定
があります。
1は、VC++の場合、プロジェクトのプロパティからリンカのコマンドラインに追加します。2は、Editbin.exeというものがあるらしいですが、詳細は謎です。
テスト
てすとー
#include <stdio.h> #include <stdlib.h> #include <windows.h> #define ALLOC_SIZE (1024 * 1024) int main(void) { void *p = NULL; size_t sum = 0; HANDLE hHeap = HeapCreate(0, 0, 0); if (hHeap == NULL) { perror("HeapCreate"); return -1; } do { p = HeapAlloc(hHeap, 0, ALLOC_SIZE); sum += ALLOC_SIZE; printf("%uKB %p\n", sum / 1024, p); } while (p != NULL); return 0; }
>cl memtest.c Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. memtest.c Microsoft (R) Incremental Linker Version 9.00.21022.08 Copyright (C) Microsoft Corporation. All rights reserved. /out:memtest.exe memtest.obj > > memtest 1024KB 00410020 2048KB 00520020 3072KB 00630020 ....(略) 1965056KB 7FD40020 1966080KB 7FE50020 1967104KB 00000000 >
OSの設定で3GBまで使えるようにしていても、アプリケーション側での対応がないと2GBまでしか使えないようです。
> link /LARGEADDRESSAWARE memtest.obj > memtest 1024KB BFAE0020 2048KB BF9D0020 3072KB BF8C0020 ....(略) 2951168KB 001E0020 2952192KB 000D0020 2953216KB 00000000 >
リンカオプションで指定すると使えるようなりました。