.NET Frameworkにおける マネージヒープと ガベージコレクション

Slides:



Advertisements
Similar presentations
独習JAVA Chapter 6 6.6 クラスの修飾子 6.7 変数の修飾子 結城 隆. 6.6 クラスの修飾 abstract インスタンス化できないクラス。1つまたは複数のサブクラスで 実装してはじめてインスタンス化できる。 final 継承されたくないことを明示する。これ以上機能拡張 / 変更でき.
Advertisements

モバイルエージェントシステムの実装 エージェント移動(状態とコードの一括移送) エージェント移動の特徴 システム構成 エージェントプログラム
6.4継承とメソッド 6.5継承とコンストラクタ 11月28日 時田 陽一
コンパイラ 2011年11月14日
アルゴリズムとプログラミング (Algorithms and Programming)
中村孝介(九州工業大学) 光来健一(九州工業大学/JST CREST)
プログラミング基礎I(再) 山元進.
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
応用情報処理V 第1回 プログラミングとは何か 2004年9月27日.
アルゴリズムとデータ構造 2011年6月13日
アルゴリズムとプログラミング (Algorithms and Programming)
応用情報処理V 第1回 プログラミングとは何か 2003年9月29日.
INSERT(x,p,L)の例 (一部) 磯 直行 2009年5月5日
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
第6回独習Javaゼミ 第6章 セクション4~6 発表者 直江 宗紀.
オブジェクト指向 プログラミング 第十四回 知能情報学部 新田直也.
9.1 DOMの概要 9.2 DOMプログラミングの基礎 9.3 DOMのプログラミング例
プログラミング言語入門 手続き型言語としてのJava
アルゴリズムとプログラミング (Algorithms and Programming)
細かい粒度で コードの再利用を可能とする メソッド内メソッドと その効率の良い実装方法の提案
第9章 例外処理,パッケージ 9.1 例外処理 9.2 ガーベッジコレクション.
独習JAVA 6.8 コンストラクタの修飾子 6.9 メソッドの修飾子 6.10 ObjectクラスとClassクラス 11月28日(金)
オブジェクト指向 プログラミング 第十一回 知能情報学部 新田直也.
オブジェクト指向 プログラミング 第十三回 知能情報学部 新田直也.
Cプログラミング演習 第7回 メモリ内でのデータの配置.
オブジェクト指向 プログラミング 第十四回 知能情報学部 新田直也.
アルゴリズムとプログラミング (Algorithms and Programming)
画像処理プログラムの説明.
メモリの準備 メモリには、その準備の方法で2種類ある。 静的変数: コンパイル時にすでにメモリのサイズがわかっているもの。 普通の変数宣言
コンパイラ 2012年11月15日
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
第7回 授業計画の修正 中間テストの解説・復習 前回の補足(クロックアルゴリズム・PFF) 仮想記憶方式のまとめ 特別課題について
アルゴリズムとデータ構造1 2005年7月5日
プログラミング基礎B 文字列の扱い.
オブジェクト指向 プログラミング 第十ニ回 知能情報学部 新田直也.
オブジェクト指向プログラミングと開発環境
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
独習Java ・ 5.7  静的変数と静的メソッド ・ 5.8  ローカル変数と変数のスコープ  11月20日    小笠原 一恵.
JAVAバイトコードにおける データ依存解析手法の提案と実装
第5回 メモリ管理(2) オーバレイ方式 論理アドレスとプログラムの再配置 静的再配置と動的再配置 仮想記憶とメモリ階層 セグメンテーション
アルゴリズムとプログラミング (Algorithms and Programming)
11: 動的メモリ確保 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと
オブジェクト指向 プログラミング 第九回 知能情報学部 新田直也.
オブジェクト指向プログラミング クラス 継承
プログラミング言語論 第十三回 理工学部 情報システム工学科 新田直也.
オブジェクト指向 プログラミング 第八回 知能情報学部 新田直也.
Boostのスマートなポインタを使ってみる
アルゴリズムとデータ構造 2012年6月11日
アルゴリズムとプログラミング (Algorithms and Programming)
アルゴリズムとデータ構造1 2006年6月23日
アルゴリズムとデータ構造1 2009年6月15日
6.5 セマフォ セマフォ(semaphore): 複数のタスク(もしくはスレッド)が「同期」または「相互排除」の制御のために取得(acquire)・リリース(release)できるカーネルオブジェクトの総称.
ユビキタスコンピューティングの ための ハンドオーバー機能付きRMIの実装
第5回 プログラミングⅡ 第5回
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
プログラムの一時停止時に 将来の実行情報を提供するデバッガ
アルゴリズムとデータ構造 2010年6月17日
ソフトウェア工学 知能情報学部 新田直也.
11: 動的メモリ確保 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
Javaとは Javaとはオブジェクト指向言語でJava VM(Java仮想マシン)と呼ばれるプログラム上で動作します。
プログラミング演習I 2003年6月11日(第9回) 木村巌.
:: の扱い 長谷川啓.
情報処理Ⅱ 小テスト 2005年2月1日(火).
C#プログラミング実習 第1回.
TList リスト構造とは? 複数のデータを扱うために、 データの内容と、次のデータへのポインタを持つ構造体を使う。
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
計算機プログラミングI 第2回 2002年10月17日(木) 履習登録 複習 ライブラリの利用 (2.6-7) 式・値・代入 (2.6-8)
計算機プログラミングI 第5回 2002年11月7日(木) 配列: 沢山のデータをまとめたデータ どんなものか どうやって使うのか
プログラミング 2 静的変数.
Presentation transcript:

.NET Frameworkにおける マネージヒープと ガベージコレクション

プログラミング.NET Framework 第4版 21章のお話

実際のオブジェクト オブジェクトヘッダ フィールド 型オブジェクトポインター(4byte, 8byte) 型の構造体へのポンタ 同期ブロックインデックス(4byte, 8byte) ロックとかCOMで利用する フィールド

リソースを割り当てる マネージヒープ NextObjPtr

リソースを割り当てる マネージヒープ オブジェクトAを割り当てたい! NextObjPtr 同期ブロック 型ハンドル フィールド 同期ブロックインデックス~ フィールドまでが入るようにする 型ハンドル フィールド

リソースを割り当てる A マネージヒープ NextObjPtr オブジェクトAを割り当てたら NextObjPtrjがオブジェクトの直後まで 進む

リソースを割り当てる マネージヒープ A B NextObjPtr

リソースを割り当てる マネージヒープ A B C NextObjPtr オブジェクトの割り当ては単なる ポインタの加算なので非常に速い

いつからマネージドヒープが 無限にあると勘違いしていた?

ガベージコレクション A B C D E F G H マネージヒープ NextObjPtr オブジェクトを割り当てようとしたが 十分なアドレス空間がのこっていない! NextObjPtr ガベージコレクション 実行!

ガベージコレクションの実行手順 全てのスレッドを一時停止 GCマーキングフェイズ コンパクションフェイズ ガベージコレクション終わるまですべてのスレッ ドがオブジェクトにアクセスできない GCマーキングフェイズ 使ってないオブジェクトを探す コンパクションフェイズ 不要なオブジェクトを削除して圧縮する

マーキングフェイズ A B C D E F G H マネージヒープ 参照を表す ルート: フィールドや 変数 マネージヒープ A B C D E F G H 参照を表す クラスの静的またはインスタンスフィールド、 メソッドの実引数、ローカル変数などで 参照型の変数を総称してルートと呼びます NextObjPtr

マーキングフェイズ A B C D E F G H マネージヒープ ルート: フィールドや 変数 マネージヒープ A B C D E F G H 全オブジェクトの同期ブロックインデックス フィールドに含まれているビットに0を指定 ⇒これはすべてのオブジェクトを  削除するという意味 NextObjPtr

マーキングフェイズ A B C D E F G H マネージヒープ 1 1 1 1 ルート: フィールドや 変数 マネージヒープ A B C D E F G H 1 1 1 1 ルートから直接参照されている オブジェクトをマークします。 NextObjPtr

マーキングフェイズ A B C D E F G H マネージヒープ 1 1 1 1 1 ルート: フィールドや 変数 マネージヒープ A B C D E F G H 1 1 1 1 1 マークをする際に、もし他のオブジェクトを 参照している場合は、そのオブジェクト もマークします。 この例だとDをマークするときはGもマークします NextObjPtr

マーキングフェイズ A B C D E F G H マネージヒープ 1 1 1 1 1 これでマーキングフェイズが完了です。 ルート: フィールドや 変数 マネージヒープ A B C D E F G H 1 1 1 1 1 これでマーキングフェイズが完了です。 マークされたオブジェクトは到達可能 といいます。 マークされていないのは到達不能といいます。 NextObjPtr

コンパクションフェイズ A B C D E F G H マネージヒープ 1 1 1 1 1 ルート: フィールドや 変数 マネージヒープ A B C D E F G H 1 1 1 1 1 マークされているオブジェクトによって 使用されているメモリを移動させて メモリ上に連続するようにします。 NextObjPtr

コンパクションフェイズ A C C D F G マネージヒープ ルート: フィールドや 変数 マネージヒープ A C C D F G オブジェクトを移動させる際に、 オブジェクトを参照しているルートなどは移動した分のバイト数を引く必要があります。

コンパクションフェイズ A C D F G マネージヒープ マークされているすべてのオブジェクトに対して 行います。 ルート: フィールドや 変数 マネージヒープ A C D F G マークされているすべてのオブジェクトに対して 行います。

なんでコンパクションが 必要なの? メモリの空容量を連続的にすることで、マネージヒープ上でメモリの断片化がなくなります。

ガベージコレクション実行しても メモリが足りないときは? OutOfMemoryExceptionの例外が発生します。 アプリケーションはその例外をキャッチして回復を試みることができますが、ほとんどのアプリケーションはやってないのでプロセスが終了して、OSがプロセスが使用していたメモリを解放します。

メソッド内の オブジェクトの生存期間 メソッド内のオブジェクトの生存期間は最後に参照したところまでです。 メソッドの終了時までじゃないです。

メソッド内の オブジェクトの生存期間 static void Main(string[] args) { Timer t = new Timer(TimerCallback, null, 0, 2000); // タイミングA Console.ReadLine(); // オブジェクトtの参照 Console.WriteLine(t.ToString()); // タイミングB }

メソッド内の オブジェクトの生存期間 static void Main(string[] args) { Timer t = new Timer(TimerCallback, null, 0, 2000); // タイミングA Console.ReadLine(); // オブジェクトtの参照 Console.WriteLine(t.ToString()); // タイミングB } オブジェクトt は保障される オブジェクトt は保障されない ガベージコレクションが 実行されたら消える

メソッド内の オブジェクトの生存期間 なおDebugでビルドした場合、JITコンパイラが生存期間を恣意的にメソッドの最後まで伸ばします Releaseビルドと Debugビルドで動きがかわるぞ! がっでむ!

世代別ガベージコレクタ CLRのGCは世代別ガレージコレクタを採用している 世代別GCは次のことを前提にしている オブジェクトが新しいほど、その生存期間は短い オブジェクトが古いほど、その生存期間は長い ヒープの一部分の回収はヒープ全体の回収より高 速である

世代別ガベージコレクタ マネージヒープ A B C D E 世代0 新しく追加されるオブジェクトは常に 世代0に追加される。

世代別ガベージコレクタ A B C D E マネージヒープ 世代0 しばらくしてオブジェクトCとEが到達不能となる その後、ガベージコレクションが発生したとする。

世代別ガベージコレクタ A B D マネージヒープ 世代1 世代0 ガベージコレクションの後に世代0で生き残った オブジェクトが世代1に移動して世代0は空になる

世代別ガベージコレクタ A B D F G H マネージヒープ 世代1 世代0 新しいオブジェクトは世代0に割り当てられていく。 世代0の予約サイズを超えた場合に ガベージコレクションが実行される。

世代別ガベージコレクタ A B D F H マネージヒープ 世代1 世代0

世代別ガベージコレクタ マネージヒープ A B D F H I J K L 世代1 世代0

世代別ガベージコレクタ A B D F H I L マネージヒープ 世代0 世代1 ガベージコレクションを実行していくと このように世代1が徐々に増加していく。

世代別ガベージコレクタ A B D F H I L M N O マネージヒープ 世代0 世代1 世代1のサイズが上限を超えた時に ガベージコレクション が発生したとしよう

世代別ガベージコレクタ A D L M O マネージヒープ 世代2 世代1 世代0 世代1~世代0のオブジェクトを検査する。 世代1の到達可能オブジェクトは世代2となる。 世代0の到達可能オブジェクトは世代1となる

世代別ガベージコレクタ 世代別にGCを行うので、すべてのオブジェクトを検査しなくてすむ。

GCの起動要因 世代0の使用量が予約サイズを超えた System.GCをコードで実行 Windowsが空容量低下の状況を報告 予約サイズはCLRが動的に決める System.GCをコードで実行 Windowsが空容量低下の状況を報告

ラージオブジェクト その1 CLRは個々のオブジェクトをスモールオブジェクトかラージオブジェクトのどちらかであると見なす ラージオブジェクト その1 CLRは個々のオブジェクトをスモールオブジェクトかラージオブジェクトのどちらかであると見なす 現在85,000バイト以上をラージオブジェクト ※ただし、変更される可能性あり ラージオブジェクトはスモールオブジェクトと違うアドレス空間に割り当てられる ラージオブジェクト⇒Large Object Heap(LOH) スモールオブジェクト⇒Small Object Heap (SOH)

ラージオブジェクト その2 現時点では、GCはラージオブジェクトに対してコンパクションを行わない。 ラージオブジェクト その2 現時点では、GCはラージオブジェクトに対してコンパクションを行わない。 ラージオブジェクトは割り当て後、すぐに世代2の一部とみなされる 世代2でGCが実行される時じゃないとラージオ ブジェクトに対してGCは行われない。

どういうことだってばよ?

どういうことだってばよ? ラージオブジェクトだとメモリの断片化(フラグメンテーション)が発生します

LOHの割り当てとGC Large Object Heap A B C D

LOHの割り当てとGC Large Object Heap A B C D オブジェクトB,Cが到達不能になった。

LOHの割り当てとGC A D Large Object Heap ガベージコレクション発生後、到達不能の オブジェクトは解放され、1つの空き容量を作成する コンパクションは行わない

LOHの割り当てとGC A E D Large Object Heap

LOHの割り当てとGC Large Object Heap  →OutOfMemoryExceptionがスルーされる可能性ある

LOHが例外を生むなら… プロセス再起動するしかないじゃない!

.NET 4.5.1 なら その必要はないわ!

メソッド内の オブジェクトの生存期間 LOHもコンパクションできる そう.NET4.5.1ならね! Using System; Using System.Runtime; // LOHに対するコンパクションを要求 GCSettings.LOHCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; // GCが発生してLOHがコンパクションされる GC.Collect(): LOHもコンパクションできる そう.NET4.5.1ならね!

ファイナライゼーション finalization オブジェクトがGCにより回収対象になった後で、オブジェクトのメモリが解放される前に何らかのコードを実行できる

Finalizeメソッド class Hoge{ // Finalizeメソッド ~Hode() { // } } C++のデストラクタと似ていますが、動作は異なる。 C++ではスコープを外れた時に、確実に呼ばれます。 C#ではFinalizeメソッドが実行されるタイミングは全く 制御できません。

ファイナライゼーションの動作 A B C D E F B C E F マネージヒープ ファイナライゼーションリスト Fリーチャブルキュー Finalizeメソッドが定義してあるオブジェクトを 割り当てる際、型インス箪笥コンストラクターが呼ばれる 前にFinalizationリストにオブジェクトのポインタが配置 される。

ファイナライゼーションの動作 A B C D E F B C E F マネージヒープ ファイナライゼーションリスト Fリーチャブルキュー C、D、Fが参照されなくなった

ファイナライゼーションの動作 A B C E F B E C F マネージヒープ ファイナライゼーションリスト Fリーチャブルキュー ガベージコレクションが実行されると、 FinalizeメソッドのないオブジェクトDは削除され、 Finalizeメソッドのあるオブジェクト、C、FはFリーチャブルキュー へ参照が移動する

ファイナライゼーションの動作 マネージヒープ A B C E F B E C F ファイナライゼーションリスト Fリーチャブルキュー

ファイナライゼーションの動作 A B C E F B E マネージヒープ ファイナライゼーションリスト Fリーチャブルキュー Fリーチャブルキューにデータが入ると、 Finalize用のスレッドが動作してキューからデータを 取り出して、Finalizeメソッドを実行します  → Fリーチャブルキューから参照が消えて、   C,Fオブジェクトは到達不能となる

ファイナライゼーションの動作 A B E B E マネージヒープ ファイナライゼーションリスト Fリーチャブルキュー その次のタイミングのガベージコレクションで オブジェクトは削除される

ファイナライゼーション finalization Finalizeを使うオブジェクトは削除されるまでに2回のガベージコレクションが必要になる。

参考 CLR オブジェクトヘッダーの構造 大きなオブジェクト ヒープの秘密 http://dotnetlogbook.blogspot.jp/2009/09/clr.ht ml 大きなオブジェクト ヒープの秘密 http://msdn.microsoft.com/ja-jp/magazine/cc53499 The Dangers of the Large Object Heap https://www.simple-talk.com/dotnet/.net-framework/the-dangers-of- the-large-object-heap/