42
THIS IS CLR

This is CLR

  • Upload
    gunda

  • View
    37

  • Download
    0

Embed Size (px)

DESCRIPTION

This is CLR. GC. GC の動作は単純明快!. ルート(オブジェクトを参照している変数)の存在しないオブジェクトを回収し、メモリを解放する。 それだけを知っていればよい。. GC は全く透過的だ!. GC の動作の詳細を知らなくても殆どにおいて問題ない。 GC はプログラム、或いはプログラマからは全く透過的だ。. だが、知識は役に立つ. パフォーマンス アンマネージリソースの確実な解放 アンマネージコードとの連携 ルートがないように見えるオブジェクトの維持 etc… 知識はトラブルシュートの役立つ. パフォーマンス. - PowerPoint PPT Presentation

Citation preview

Page 1: This is CLR

THIS IS CLR

Page 2: This is CLR

GC

Page 3: This is CLR

GCの動作は単純明快! ルート(オブジェクトを参照している変数)の存在しないオブジェクトを回収し、メモリを解放する。 それだけを知っていればよい。

Page 4: This is CLR

GCは全く透過的だ! GC の動作の詳細を知らなくても殆どにおいて問題ない。 GC はプログラム、或いはプログラマからは全く透過的だ。

Page 5: This is CLR

だが、知識は役に立つ パフォーマンス アンマネージリソースの確実な解放 アンマネージコードとの連携 ルートがないように見えるオブジェクトの維持 etc…

知識はトラブルシュートの役立つ

Page 6: This is CLR

パフォーマンス Finalize を実装するかしないかで、そのクラスのオブジェクトの GC パフォーマンスは大きく変わる。 Finalize を実装しているクラスのオブジェクトは一度の GC では決して回収されない。

Page 7: This is CLR
Page 8: This is CLR
Page 9: This is CLR
Page 10: This is CLR
Page 11: This is CLR

パフォーマンスが悪い! Finalize 実装オブジェクトは最低でも 3 回以上(ジェネレーション昇格も発生)の GC 実行後にしか回収されない。

Page 12: This is CLR

アンマネージリソースの確実な解放 アンマネージリソースを持つクラスは、アンマネージリソースを確実に解放するために

Finalize を実装する。 加えて、任意のタイミングで解放できるように

Dispose パターンも使用する。

Page 13: This is CLR

Finalizeを実装したら確実か? Finalize を実装したからといって確実に呼ばれるとは限らない。 Finalize 呼び出し時に、 Finalize メソッドを

Jit compile できないぐらいメモリが逼迫していたらどうなる?

Page 14: This is CLR

CriticalFinalizerObject インスタンス化と同時に Finalize メソッドを

JIT COMPILE してしまう。 通常の Finalize 実装クラスの後に

CriticalFinalizerObject の Finalize を呼ぶ。

Page 15: This is CLR

アンマネージコードとの連携 GC の仕事は、使われなくなったオブジェクトを解放するだけではないという事も覚えておこう。 穴空きになった Mange heap をコンパクションし、使用中のメモリを一ヶ所に集める。

Page 16: This is CLR

オブジェクトは動く マネージコード内のオブジェクトのアドレスは不定 GC を備えていない実装系ではオブジェクトのアドレスが動くという想定はしていない。

Page 17: This is CLR

オブジェクトを固定する マネージコートとアンマネージコードを連携するにはアドレスを固定、或いは代替アドレスを使用する必要がある。

Page 18: This is CLR

GCHandle AppDomain 毎に一つ存在する GCHandle

Table を利用し、固定されたアドレスを得る。

Page 19: This is CLR

GCHandleType.Normal // オブジェクトを GCHandle Table に登録する。 object objectA = new object(); GCHandle gh1 = GCHandle.Alloc(o,

GCHandleType.Normal); IntPtr p = (IntPtr)gh1 // p をアンマネージコードに渡す。 // p のアドレスは決して動かない。 ・・・ // アンマネージコードから p がコールバックされる。 GCHandle g = (GCHandle)p; object o2 = g.Target;

Page 20: This is CLR

GCHandleType.Normal

Page 21: This is CLR

GCHandleType.Pinned // オブジェクトを GCHandle Table に登録する。 object objectA = new object(); GCHandle gh1 = GCHandle.Alloc(o,

GCHandleType.Pinned); // objectA のアドレスををアンマネージコードに渡す。 // objectA のアドレスは決して動かない。 ・・・ // アンマネージコードから objectA を直接触る。

Page 22: This is CLR

GCHandleType.Pinned

Page 23: This is CLR

何故 Formが消えない? void Func() { Form1 f = new Form1(); f.Show(); }

GCHandle のインスタンスを内部に持ち、自身を Target としている。

Page 24: This is CLR

AppDomainとassembly

Page 25: This is CLR

殆どのプロセスはシングルAppDomain AppDomain など知らなくても問題ない。殆どのアプリケーションはたった一つの

AppDomain で動作する(ように見える)。

Page 26: This is CLR

Single AppDomain

Page 27: This is CLR

Multi AppDomain

Page 28: This is CLR

Multi AppDomain assembly は AppDomain 単位で各々にロードされる。 Jit コンパイルされたネイティブイメージも各々の AppDomain が持つ。

Page 29: This is CLR

Domain Neutral

Page 30: This is CLR

Domain Neutral ドメイン中立にある assembly はプロセス内の全ての assembly で共有する。 Jit コンパイルされたネイティブイメージも共有できる。 static データは各々の assembly でコピーが必要。 しかし、各プロセスでそれぞれ Jit コンパイルする必要がある。

Page 31: This is CLR

Ngen 状態

Page 32: This is CLR

Ngen 状態 ngen.exe で予めネイティブイメージを作っておくと全てのプロセスでコードページを共有できる。

Page 33: This is CLR

side-by-side

Page 34: This is CLR

side-by-side

Page 35: This is CLR

side-by-side .NET アプリケーションは「コンパイルタイム」の環境がそのまま「ランタイム」の環境となる。

Page 36: This is CLR

バージョンリダイレクト

Page 37: This is CLR

バージョンリダイレクト side-by-side で動作させるのは、最終手段である。基本はバージョンアップ後のライブラリで動作するのが望ましい。

Page 38: This is CLR

.NET Framework Unification

Page 39: This is CLR

.NET Framework Unification

Page 40: This is CLR

.NET Framework Unification

一つのプロセスには一つの CLR しかロードできない。 CLR のバージョンと mscorlib のバージョンは必ず同一でなければならない。 CLR のバージョンと mscorlib 以外の .NET

Framework Class Libarry のバージョンは必ずしも同一でなくてもよい。

Page 41: This is CLR

.NET Framework Unification

DEMO

Page 42: This is CLR

ご静聴ありがとうございました。