CLR Hosting : 仮想メモリ編 (1)

地味に需要あるのかもしれないですなぁ.arton さんのところと MSDN Forums より.

Java と比べれば CLR Hosting API は How to 記事を書いて一発というわけにはいかないぐらい (MSDN に正確な仕様が書いてないぐらい) 暗部で,かつ苦労の割にうまく行くかどうか分からないという暗黒感たっぷりですが,ちょっとだけ時間がとれたので試してみました.例によって参考書はいつもの本ですが,今回は毛色を変えて MSDN Magazine の最新記事の引用文でも.


簡潔さを目指したために、多数の基本事項を省略しました。CLR のホスト機能の完全な概要に関しては、Steven Pratschner 氏の著書 Customizing the Microsoft .NET Framework Common Language Runtime (Microsoft Press、2005 年版) を参照してください。



今回は,CLR Hosting API を使用して,CLR が使用する Virtual Alloc/Virtual Free をフックするコードサンプルを作ってみました.ヒープサイズを制限するというところまでは行っていませんが,OutputDebugString で各 API 呼び出しのログを出力しています.
http://www.dwahan.net/nyaruru/hatena/CLRVM.zip

試してみて分かりましたが,SQL Server 2005 のように CLR の使用メモリ量を制限するのは,案外大変です.例えばアドレス 0x018f0000 から 0x038effff までを VirtualAlloc で確保したコミットした後,0x03000000 から 0x038effff までをデコミットできるかどうか? できるとしてどうなるか? といった部分をちまちまと詰めていく必要があります.なにげに結構面倒.
とりあえずある程度動いている版は main.cpp で g_ManagerMode に Mode_ReportEx を設定すると動きます.
これもデバッグメッセージに流すだけでまともな整形はやっていませんが,C# 側で延々オブジェクトの生成を行っていると次のように予約領域が徐々にコミットされていくのが見えてきます.

0x038a0000 - 0x0489ffff : 16777216 byte ( 10285056 byte committed)
    ↓
  オブジェクト確保
    ↓
  VirtualAlloc: MEM_COMMIT from 0x0426f000, 65536 byte 
    ↓
0x038a0000 - 0x0489ffff : 16777216 byte ( 10350592 byte committed)
    ↓
  オブジェクト確保
    ↓
  VirtualAlloc: MEM_COMMIT from 0x0427f000, 65536 byte 
    ↓
0x038a0000 - 0x0489ffff : 16777216 byte ( 10416128 byte committed)

後はまあ予約サイズまたはコミット済みサイズに基づいて,ある一定以上のリソースを要求する VirtualAlloc を失敗させてみるという感じでしょうかね.実装まだですけど.