.NET アプリケーションのメモリ種類
[1] スタック(ローカル変数を保持するための空間。容量が比較的小さい。) [2] ヒープ(参照型のデータのインスタンスを保持するための空間。容量が非常に大きい。) [2-1] アンマネージ ヒープ [2-2] マネージ ヒープ
CLR ( Common Language Runtime )
* メモリの確保・解放は、CLR ( Common Language Runtime )によって管理されている * CLR がもつガベージコレクタによって、不要になったメモリは自動的に解放される
ガベージ コレクション
http://msdn.microsoft.com/ja-jp/library/ms998547.aspx#scalenetchapt05_topic10より * アプリケーションのアロケーション プロファイルを特定して分析する。 * GC.Collect の呼び出しを避ける。 * キャッシュ データ について弱い参照の使用を検討する。 * ライフ サイクルの短いオブジェクトを昇格させない。 * 所要時間の長い呼び出しをする前に不要なメンバ変数を null に設定する。 * 隠れたアロケーションを最小限に抑える。 * 複雑なオブジェクト グラフを避けるか最小限に抑える。 * メモリのプリアロケートとチャンクを避ける。
ジェネレーション(世代)
ジェネレーションとは
[1] 生成されてから間もないオブジェクト [2] 時間が経過したオブジェクト => 一般的に、作成されてから時間が経過したオブジェクトは解放される可能性が低く、 生成されてから間もないオブジェクトは解放される可能性が高いことから、 後者のオブジェクトだけを調べて解放処理を行うことで効率アップするhttp://www.atmarkit.co.jp/fdotnet/dotnettips/021gc/gc.html
より抜粋 * ベージ・コレクションを効率よく実行するために、 .NETのガベージ・コレクタは、ジェネレーション(世代)という概念を採用しているhttp://uchukamen.com/Programming/GC/#.NET_Framework_のメモリ管理の内部動作
より * .NET では、Generation 0(新), 1, 2(古) の3世代でメモリ管理している (現在の.NET Frameworkには3つのジェネレーション(ジェネレーション0、1、2)がある) * 全てのオブジェクトは、Generation 0(ジェネレーション0) として生成 * Collectメソッドでガベージ・コレクションを行うと、 その時点で残ったオブジェクトはジェネレーションが1つ古い方にずれる
LOH(Large Object Heap,大きなオブジェクト)について
http://msdn.microsoft.com/ja-jp/magazine/cc534993.aspxより抜粋 * .NET1.1/2.0 では、オブジェクトのサイズが 85,000 バイト以上の場合に、大きなオブジェクト(LOH)と見なす * 大きなオブジェクトは、ジェネレーション2 に属す * 世代 2 に対して GC.Collect が呼び出されると、直ちに収集されます。
参考文献
http://d.hatena.ne.jp/torutk/20100529/p1Dispose() と null代入
http://social.msdn.microsoft.com/Forums/ja-JP/vsgeneralja/thread/65c3c5fe-036a-457b-9d6a-0e418f0f4770より * Dispose() は、アンマネージリソースの解放 * Dispose() 後のnullの代入が必要ない
null代入
http://msdn.microsoft.com/ja-jp/library/ms998547.aspx#scalenetchapt05_topic10より * 自分のクラス、または他のクラスで不要になった静的変数を null に設定すること * 所要時間の長い呼び出しの前に破棄可能なオブジェクトがあれば、それらを null に設定すること * ローカル変数は null を設定しないこと void func(...) { String str1; str1="abc"; // これを避ける str1=null; }
配列の解放
http://msdn.microsoft.com/ja-jp/library/cc406736.aspxには、nullの代入について、「配列の実体は、この時点で誰からも参照されなくなり、解放の候補としてマークされ」ると記載されている。 null代入は、配列ではやった方がいいってことか?