投稿数 - 437, コメント - 53257, トラックバック - 156

This is CLR - GC (Section 2)

This is CLR - GC (Section 1)

GC の動作は単純明快。「ルート(オブジェクトを参照している変数)の存在しないオブジェクトを回収し、メモリを解放する」ただそれだけである。殆どにおいて、プログラム、或いはプログラマからは GC は全く透過的だ。GC の動作の詳細を気にする必要はない。だが、GC について知識を持っていると役に立つ事がある。パフォーマンス、アンマネージリソースの確実な解放、アンマネージコードとの連携、ルートがないように見えるオブジェクトの維持、ルートがあるように見えるオブジェクトの GC 回収、etc。知識は無用なトラブルを回避してくれる。

 

  • アンマネージリソースの確実な解放

アンマネージリソースを内部リソースとして持つクラスは Finalize を必ず実装しなければならない。更に、Dispose パターンを使って、任意のタイミングでアンマネージリソースを解放できるようにすれば尚良しだ。しかし、Dispose の実装は「できればしたほうがよい」レベルだが(※1)、 Finalize の実装は「必ずしなければならない」レベルである。そうでなければ、アンマネージリソースは Windows プロセスが終わるか AppDomain が Unload されるまでキープされる(※2)事になる。だが、Finalize を実装すれば必ずアンマネージリソースは解放されるという事でもない。例えば、Finalize を呼び出す際に CLR は Finalize メソッドを Jit compile するが、その際に Jit compile 後のネイティブコードを格納する場所がないぐらいメモリが逼迫していたらどうなるだろうか。Finalize メソッドが実行されないでアンマネージリソースがリークしてしまうのである(※3)。

では、絶対確実に Finalize が呼ばれるようにするにはどうしたらよいのか。CriticalFinalizerObject を使えばよい。.NET 2.0 から追加されたこのクラスを、Finalize を絶対確実に呼んで欲しいクラスが継承する。CLR は CriticalFinalizerObject から派生しているクラスを特別扱いする。対象クラスのオブジェクトがインスタンス化されると同時に Finalize メソッドもコンパイルしてしまう(※4)。こうする事によって、Finalize メソッドがコンパイルされていないという状況は存在しない。更に、Finalize 呼び出し順序にも影響を与える。前回は、Finalize の呼び出し順に何のルールも存在しないと説明したが、CLR は通常の Finalize を実装しているオブジェクトの Finalize を呼び出した後に CriticalFinalizerObject の Finalize を実装しているオブジェクトの Finalize を呼び出す。こうする事によって、通常の Finalize メソッド内からクリティカルオブジェクトを参照する事ができるのである。

実際には、CriticalFinalizerObject から直接派生したクラスを作成する事は殆どないだろう。継承モデルは使いやすいとはいえない。.NET Framework Class Library の SafeHandle クラスや CriticalHandle クラスを使用する事になる。これらは CriticalFinalizerObject を継承している。Thread クラスも CriticalFinalizerObject だ。

信頼性の高いシステムを構築するには、CER: Constrained Execution Region「制約された実行領域」を参考の事。SQL Server のようなクリティカルなシステムでは、リソースリークを回避する事は非常に大切な事となる(※5)。

 

※1 設計思想としては、必ず実装した方が良いと言うべきだが。
※2 より明確な言い方はリーク。
※3 ただ、そのようにメモリが逼迫した状況であった場合、何らかの対処が必要となるだろう。
※4 もはやジャストインタイムとは呼べないか?
※5 SQL Server はおいそれとはプロセスのリサイクルはできない。

投稿日時 : 2007年3月21日 10:39

フィードバック

# This is CLR - GC (Section 1)

This is CLR - GC (Section 1)
2007/03/21 10:42 | 囚人のジレンマな日々

# re: This is CLR - GC (Section 2)

> 実際には、CriticalFinalizerObject から直接派生したクラスを作成する事は殆どないだろう。継承モデルは使いやすいとはいえない。

こーいうのは属性にしてくれりゃいいのにナァ…
2007/03/22 9:13 | シャノン

# re: This is CLR - GC (Section 2)

>こーいうのは属性にしてくれりゃいいのにナァ…

確かにそうですナァ…
2007/03/22 23:14 | 囚人

# re: This is CLR - GC (Section 2)

制約上属性では難しいとかあったりして。

まあ、実際のところFinalizeを自分で実装することってめったにないので、
あんまり関係ないですけどね。
2007/03/31 18:43 | なちゃ

# re: This is CLR - GC (Section 2)

>まあ、実際のところFinalizeを自分で実装することってめったにないので、

実際のところそうですね。ましてや、CriticalFinalizerObject を実装する機会など稀有になりますね。
2007/03/31 23:25 | 囚人

# re: This is CLR - GC (Section 2)

??? ??? ???????? ????? ?? ?????? ???? ??? ???? ???? ??? ??????? ?????? ?? ???? ??? ??? ???? ????? ????? ??? ???? ??????? ?????? ??????? ????? ??? ???. ????? ??? ????? ???? ?????? ????? ????????? ???????? ?????? ????? ??? ???????? ??? ????? ?? ???? ?????? ????? ???? ???? ??????? ????? ?????? ?? ?????? ???? ?? ???? ????? ????? ??????? ?? ???? ?????? ??? ?????? ?? ????? ???? ????? ?????? ???? ???? ????? ????? ?? ???? ????? ?????? ????? ???? ??????? ???? ???? ?? ????? ????? ????? ???? ??? ?????? , ????? ?????? , ?????? ??????
2016/04/12 3:08 | تنظيف الجسم

# tadalafil sublingual average dose

https://buylasixshop.com/ - Lasix
2021/09/16 9:43 | abobbergy

コメントの投稿

タイトル
名前
URL
コメント