[csharpll:0328] Re: <教> リソース解放のタイミング

Subject:
[csharpll:0328] Re: <教> リソース解放のタイミング
From:
Kouji Suzuki <k@...>
Date:
Mon, 20 Mar 2006 18:01:07 +0900
X-Mailer:
Microsoft Outlook IMO, Build 9.0.6604 (9.0.2911.0)
Message-Id:
<LNEFLJOMMEELLFMOGANPOEJJDOAA.k‐at‐kekyo.net>
In-Reply-To:
316
kekyo@お久しぶりです。

> C#にはあるみたいやけど > デストラクタ

C#のデストラクタは構文上はC++のデストラクタと同じですが、
コンパイルすると Finalize() になります。

ファイナライザ(とDispose)の実装がJavaと違ってややこしく
感じるのは、アンマネージリソースの制御を支配できるからです。

Dispose()が明示的に呼び出された場合、そのクラス内で暗黙に
(有効な)他のオブジェクトへの参照を保持しているか、
あるいは全く保持していないので、Dispose()の実装は安全に
動作することができます。

しかし、Finalize()内ではもはやクラスで保持している参照は
無効となっている可能性があるため、うかつに操作出来ません。

#なんだったか、そこで無効な参照を操作すると例外が出た
#ような気がしますが未確認。

では、Finalize()では何もできないのかというとそうではなく、
無効な参照さえ使用しなければ、アンマネージリソースの解放が
出来ます。
たとえば、IntPtr型で保持した値は参照ではなく値型なので
これを使って解放できます。

#ファイルハンドル類とかメモリのハンドルはIntPtrに入って
#いるので、CloseHandle() みたいなことをすればよい。

この問題とDispose()の実装をうまくするために、プログラミング
..NET Framework P.475で示されるような実装を行うことを
推奨しています。

Dispose()は明示的に呼び出さない限りは、GCが呼び出すことは
ありません(C#ではusingのブロックを出るときにDispose()を
呼び出すfinalizeを生成できるけど同じです)。

GCがIDisposableを実装していることを検知して、自動的に
Dispose()を呼び出してくれれば良いのに、と思ったことも
ありますが、以上のような理由で

「そのタイミングでDispose()が呼ばれても困ったチャンになる」

ためにそうなっていないのだと思います。

> GC が働く前にプロセスが終了してしまう場合などはファイナライザ
> が呼び出されることは保証されていないはずです。

これ、私も必ず呼び出されると思っていたのですが、
実際は呼び出されないことがありました。
OSのプロセスが終了する場合は、OS自身がアンマネージ
リソースを解放できるからだと思っています。

私もC++のようにデストラクタを活用したい口なので、
しかたなくusing書きまくってます。

> いや、Javaのときも感じたんだけど、
> 「ガベコレあるから散らかしっぱなしにできて楽ちん」
> ってのは"うそっぱち"ですよね? 少なくともメモリ以外のリソース
> を使ったんならプログラマが責任もってお片づけしたらんと。

禿同禿同 :-)
結局、ちゃんとコントロールすることが大事だし、
そうせざるを得ないです。

ちなみに、2.0ではまた調べてませんが、ADO.NETの実装で
DBへの接続のClose()とDispose()は意味合いが異なるので
注意が必要です。

#どうせならICloseableを作ったほうが良かったのではと。

----------------------
Kouji Suzuki / Microsoft Certified Professional
mailto:k@...
# 実行形式の添付ファイルかHTMLメールは自動的に廃棄されます。
# It will be automatically discarded if the attached file of
# executable files or "HTML mail" is transmitted to this mail address.

スレッド

Navigation

検索

[検索ヘルプ]

Maintener: Tietew <www.tietew.jp>
Powered by Ruby on Rails, Mongrel, PostgreSQL, and Hyper Estraier.
click here