[csharpll:0317] Re: <教> リソース開放のタイミング
小野@どっとねっとふぁん です。
----- Original Message -----
From: "FUKUDA, Fumiki" <fukuda.fm@...>
Subject: [csharpll:0314] <教> リソース開放のタイミング
> すんません、基本的なこと確認させてくださいませ。
> C#では(.NETならなんでもいいけど)、メモリの開放はガベコレ時に
> 行われますけど、メモリ以外のリソースは何時開放されるんでしょか?
実際には実装依存、、、だっけかな?
> こんなとき、ファイルがクローズされるのは何時なんでしょか?
> デストラクタ内で後始末(Close)してるなら、
> ガベコレ直前にデストラクタが動いて…ことになるんすか?
>
> 裏を返せばガベコレなんて何時動くかわかったもんじゃないから、
> 確実にClose()したいなら明示的にClose()を呼べ。ってことでしょか。
>
> あるいはデストラクタ内でCloseしてるんなら、using(...)で囲んで
> おけばスコープ外れるときにDisposeされ、そこでデストラクタが呼ばれて
> めでたくCloseなのかな?
お作法としては、Disposeにリソースを開放する処理を書いて
おきましょう、だったと思います。
で、usingで囲んだときは、スコープを外れるとDisposeが呼ばれるので
そこでリソースの開放が行われるようになる、と。
それと、GCがメモリを回収する際、Disposeが存在しているものに
ついてはまずDisposeを呼ぶという実装がなされているので、GCで
回収されるときもリソースの回収はおこなわれるはず。
#ただし、このとき一回めのGCではDisposeが呼ばれるだけなので
インスタンス自体は残っちゃうんだったよーな。
このあたりについては「プログラミング Microsoft .NET Framework」に
詳しく書いてあったと思います。
Closeに関しては特にこの手のお作法がなかったよーな。
まぁ、普通Closeなんてメソッドつくればそこでリソースの開放は
するんでしょうけど。
> いや、Javaのときも感じたんだけど、
> 「ガベコレあるから散らかしっぱなしにできて楽ちん」
> ってのは"うそっぱち"ですよね? 少なくともメモリ以外のリソース
> を使ったんならプログラマが責任もってお片づけしたらんと。
Disposeのお作法どおりにつくられてるならGC時点での回収は
保障されるので、気にしなくても一応は動くはず、というレベルですね。
Disposeが実装されてるものはなんでもかんでもusing使え、というのが
あったよーな。。。
----------------------------------------
小野@どっとねっとふぁん でした。
http://dotnetfan.org/
----------------------------------------
----- Original Message -----
From: "FUKUDA, Fumiki" <fukuda.fm@...>
Subject: [csharpll:0314] <教> リソース開放のタイミング
> すんません、基本的なこと確認させてくださいませ。
> C#では(.NETならなんでもいいけど)、メモリの開放はガベコレ時に
> 行われますけど、メモリ以外のリソースは何時開放されるんでしょか?
実際には実装依存、、、だっけかな?
> こんなとき、ファイルがクローズされるのは何時なんでしょか?
> デストラクタ内で後始末(Close)してるなら、
> ガベコレ直前にデストラクタが動いて…ことになるんすか?
>
> 裏を返せばガベコレなんて何時動くかわかったもんじゃないから、
> 確実にClose()したいなら明示的にClose()を呼べ。ってことでしょか。
>
> あるいはデストラクタ内でCloseしてるんなら、using(...)で囲んで
> おけばスコープ外れるときにDisposeされ、そこでデストラクタが呼ばれて
> めでたくCloseなのかな?
お作法としては、Disposeにリソースを開放する処理を書いて
おきましょう、だったと思います。
で、usingで囲んだときは、スコープを外れるとDisposeが呼ばれるので
そこでリソースの開放が行われるようになる、と。
それと、GCがメモリを回収する際、Disposeが存在しているものに
ついてはまずDisposeを呼ぶという実装がなされているので、GCで
回収されるときもリソースの回収はおこなわれるはず。
#ただし、このとき一回めのGCではDisposeが呼ばれるだけなので
インスタンス自体は残っちゃうんだったよーな。
このあたりについては「プログラミング Microsoft .NET Framework」に
詳しく書いてあったと思います。
Closeに関しては特にこの手のお作法がなかったよーな。
まぁ、普通Closeなんてメソッドつくればそこでリソースの開放は
するんでしょうけど。
> いや、Javaのときも感じたんだけど、
> 「ガベコレあるから散らかしっぱなしにできて楽ちん」
> ってのは"うそっぱち"ですよね? 少なくともメモリ以外のリソース
> を使ったんならプログラマが責任もってお片づけしたらんと。
Disposeのお作法どおりにつくられてるならGC時点での回収は
保障されるので、気にしなくても一応は動くはず、というレベルですね。
Disposeが実装されてるものはなんでもかんでもusing使え、というのが
あったよーな。。。
----------------------------------------
小野@どっとねっとふぁん でした。
http://dotnetfan.org/
----------------------------------------
▼ スレッド
- 314: すんません、基本的なこと確認させてくださいませ。 C#では(.NETならなんでもいいけど)、メモ FUKUDA, Fumiki
- ├315: finally で明示的に Close() を呼ぶか、using を使う必要があった と思います。 GC があるけど、デス Imabeppu
- │└316: んむ。using(...) はデストラクタがちゃんと後始末(Close)して くれてれば、って但し書きがつくん FUKUDA, Fumiki
- │ ├318: Dispose ですね。 あるにはあるんですけど、using 使わないと呼び出されるタイミング が C++ と違 Imabeppu
- │ │├320: そかそか「スコープ外れたら直ちに起動」じゃないか。 「GCのついでに」なんだな。 ヘタすり FUKUDA, Fumiki
- │ │└327: アレはデストラクタと呼ばれているけど実体はファイナライザです。 GCが開放するときにしか Tietew
- │ └328: C#のデストラクタは構文上はC++のデストラクタと同じですが、 コンパイルすると Finalize() にな Kouji Suzuki
- │ └329: 訂正。 上記はデバッガで確認したもので、実際にはFinalize()で発生した 例外はGCでにぎりつぶさ Kouji Suzuki
- │ └330: まとめてみる。間違いあったら突っ込んでおくんなさい。 auto: スコープから外れたらデストラ FUKUDA, Fumiki
- │ ├331: heapの場合、GCされるのを待たずとも明示的にdeleteすることで デストラクタを確実に呼び出すこ FUKUDA, Fumiki
- │ ├332: C++/CLIでは、~X()はIDispose::Dispose()と、!X()はFinalize()と(ほぼ)同義で す(「ほぼ」と書いたのは親ク Satoshi Nakamura
- │ │└333: 子::!子()されたとき、親::!親()は呼ばれないってことですか? それともC#では子.Finalize()時に親.Fil FUKUDA, Fumiki
- │ └334: auto: スコープから外れたらデストラクタ X::~X() が'必ず'動く。 heap: 明示的にdeleteされたらX::~X() FUKUDA, Fumiki
- └317: 実際には実装依存、、、だっけかな? お作法としては、Disposeにリソースを開放する処理を書い S.Ono
- └319: なんだかなー… なんもかんもusingでくるめって薦めるくらいなら、 FUKUDA, Fumiki
- └321: automatic 変数を許すとして、どんな書き方になるんでしょうね。 特別な書き方をするなら、using Imabeppu
- └322: んむ。 C++/CLIだと: Sister^ one = gcnew Sister("恭子"); // GC-heap Sister two("美香"); // auto(stack) なんすけど FUKUDA, Fumiki
- └323: 参照してくれてる人がいるかどうかの確認なら楽 (っつ〜か参照カウン タ使えば一瞬) なんだけ Takao Ono
- └324: デストラクタ(というかファイナライザというか)は必ずしも呼び出されることが 保障されてな S.Ono
- └325: 遅くとも GC のタイミングで必ず呼出されることが保証されてます. こっちは using を使えば本体 Takao Ono
- └326: GC が働く前にプロセスが終了してしまう場合などはファイナライザ が呼び出されることは保証 Shinichi Aoyagi