【.NET】メモリ管理 ~知識編~

.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/p1

Dispose() と 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代入は、配列ではやった方がいいってことか?

参考文献

MSDN

マネージ コードでのメモリ リークの識別と回避

http://msdn.microsoft.com/ja-jp/magazine/cc163491.aspx

自動メモリ管理

http://msdn.microsoft.com/ja-jp/library/aa691138.aspx

メモリの問題を調べる

http://msdn.microsoft.com/ja-jp/magazine/cc163528.aspx

.NET アプリケーションのメモリ使用量の監査

http://msdn.microsoft.com/ja-jp/magazine/dd882521.aspx

メモリの問題を調べる

http://msdn.microsoft.com/ja-jp/library/ms954591.aspx

スレッドとオブジェクトインスタンス

http://blogs.msdn.com/b/nakama/archive/2008/12/18/9231090.aspx

ガベージ コレクタの基本とパフォーマンスのヒント

http://msdn.microsoft.com/ja-jp/library/ms973837.aspx

ガベージコレクション入門: Microsoft .NET Framework の自動メモリ管理 Part I

http://msdn.microsoft.com/ja-jp/library/bb985010.aspx

ガベージコレクション入門: Microsoft .NET Framework の自動メモリ管理 Part II

http://msdn.microsoft.com/ja-jp/library/dd297765.aspx


関連記事

ガベージ・コレクション(Garbage Collection、GC

http://blogs.yahoo.co.jp/dk521123/29621938.html

モリー管理 ~メモリーリーク調査ツール編~

http://blogs.yahoo.co.jp/dk521123/30154754.html

メモリ管理 ~知識編~

http://blogs.yahoo.co.jp/dk521123/30157489.html