メモリ マネージャを構成する
メモリを管理する:インデックス への移動
このセクションであ、32 ビット Windows および 64 ビット Windowsでメモリ マネージャを構成する方法を説明します。他のプラットフォームでは Posix/32 メモリ マネージャを使用しており、この機能はサポートされていません。
メモ: メモリ マネージャを使用している間は、その構成を変更できます。 すべての構成がグローバルなので、メモリ マネージャを使用しているすべてのスレッドに影響を与えます。特に説明がない限り、すべての関数と手続きはスレッド セーフです。これらの構成オプションは、ローカルのメモリ マネージャにのみ適用されます。 ライブラリがメイン アプリケーションのメモリ マネージャを共有している場合は、ライブラリ内でこれらのオプションを設定しても無効です。
メモリ マネージャのブロック アラインメントの最小値を設定するには:
- GetMinimumBlockAlignment 関数を使用して、ブロック アラインメントの現在の最小値を取得します。
- アプリケーションに対する適切なメモリ ブロック アラインメントを選択します。 選択可能なブロック アラインメントは、8 バイト(System.mba8Byte)と 16 バイト(System.mba16Byte)です。
- メモリ ブロック アラインメントを変更するには、SetMinimumBlockAlignment 手続きを使用します。
メモ: メモリ マネージャによって割り当てられたメモリには、少なくとも 8 バイト境界のアラインメントが保証されます。 16 バイトのアラインメントは、SSE 命令を使用してメモリ ブロックを操作する際に有用です。 ただし、メモリ使用のオーバーヘッドが増えます。
停止時にメモリ リークを報告するには:
- グローバル変数 System.ReportMemoryLeaksOnShutdown を True に設定します。
- メモリ マネージャを停止するときに、メモリ プールをスキャンして、未登録のメモリ リークをすべてメッセージ ダイアログに出力します。 予想されるメモリ リークを登録または登録解除するには、RegisterExpectedMemoryLeak 手続きと UnregisterExpectedMemoryLeak 手続きを使用します。
メモ: メモリ マネージャは、割り当てられたメモリのうち、メモリ マネージャの停止時点でまだ解放されていないものを報告します。 このようなメモリ ブロックは、メモリ リークと呼ばれ、プログラミング エラーの結果として発生することがよくあります。 System.ReportMemoryLeaksOnShutdown のデフォルト値は False です。 リークのクラスは、ブロック内の最初の dword を調べることによって決定されます。 報告されたリークのクラスは、必ずしも 100% 正確とは限りません。 リークが AnsiString に見える場合は、文字列のリークとして報告されます。 メモリ マネージャがリークのタイプを判断できない場合は、不明のクラスに属するとして報告されます。
メモリ マネージャでスレッド競合が発生した時にスリープしないようにするには:
- グローバル変数 System.NeverSleepOnMMThreadContention を True に設定します。
- メモリ マネージャ内でスレッド競合が発生した場合、メモリ マネージャは競合が解消するまでループ内で待ちます。
メモ: メモリ マネージャは共有リソースなので、アプリケーション内のたくさんのスレッドが 1 つのメモリ マネージャ操作を同時に実行しようとすると、1 つ以上のスレッドが、他のスレッドが操作を完了するまでの間、操作を保留にして待たなければなりません。 この状況を スレッド競合 と呼びます。 メモリ マネージャ内でスレッド競合が発生すると、デフォルトの動作では、そのスレッドのタイム スライス内の残り時間を放棄します。 スレッドが次のタイム スライスに入ったときに、リソースがまだ利用できない場合、メモリ マネージャは、OS の Sleep 手続きを呼び出して、再試行までの待ち時間を強制的に長くします(約 20 ミリ秒)。
この動作は、単一 CPU または デュアル コア CPU を持つマシンに対しては効果的に機能します。 また、実行スレッド数と CPU コア数の比率が比較的高い(2:1 より高い)場合にも効果的です。 それ以外の場合は、リソースが利用可能になるまで待ち状態ループに入る方が、より高いパフォーマンスが得られる可能性があります。 System.NeverSleepOnMMThreadContention を True にすると、メモリ マネージャはスケジューリングを放棄せずに、待ち状態ループに入ります。 System.NeverSleepOnMMThreadContention のデフォルト値は False です。
メモリ マネージャのソースを取得する
メモリ マネージャ(FastMM)の全ソース コードが、GitHub リポジトリ から入手可能です。
FastMM の完全版では、メモリ マネージャを特別な "デバッグ" モードで実行できます。このモードはヒープ破損やメモリ リークの検出に役立ちます。 また、FastMM 完全版には以下の付加的機能があります。
- オブジェクト/インターフェイスの二重解放バグのサポート
- ファイル ログとレポート
詳細は、FastMM ソース コード(FastMM4.pas と FastMM4Options.inc)内のコメントを参照してください。