- - PR -
変数に対するメモリの使い方について
投稿者 | 投稿内容 | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2006-06-12 12:56
Dispose の実装はそれぞれ違いがあるから気をつけなければいけない
っていうことでしょうか。 とりあえず IDispose を実装していれば using または try...finally を使って 破棄を確実にしてあげることが大切なんですよね。 Oracle.DataAccess.Client.OracleConnection の場合こんな記述がありました。
http://otndnld.oracle.co.jp/beginner/odpnet/2_1/index.html | ||||||||||||||||
|
投稿日時: 2006-06-12 14:04
決定論的な実装指針が示されていないので、一般論としてはそういうことになります。
IDisposable.Dispose() を確実に呼び出すことで、「最悪の場合」でもアンマネージリソースが解放され、アンマネージリソースの解放漏れによる問題を回避することが出来ます。 ただし、IDisposable.Dispose() 呼び出しによって「アンマネージリソース解放以外の終了処理」がすべて正常に行われる保証は無い(=少なくとも IDisposable.Dispose() の定義はそれを求めていない)ので、Close() 呼び出しをサボって IDisposable.Dispose() 呼び出しのみを行った場合、クラス実装によっては何らかの喜ばしくない副作用があるかもしれません。 これは、IDisposable.Dispose() 云々というよりは、クラス設計・実装の問題です。
うれしくない実装ですね ;-p 何か勘違いしてるとしか思えない。。。 | ||||||||||||||||
|
投稿日時: 2006-06-12 16:11
究極的な話、どちらかを選ぶならです。 私自身は Using と Try 〜 Finally + Close で入れ子にしています。 ひどりさんは、Close メソッドは正常処理としてなので Finally での実装はしない、でしたよね? このあたりの指針は、人によって若干異なりますね。 IDisposable.Dispose メソッドが、隠蔽されていても呼ぶ なんて流派もいますね。 私は、そこまで過激派ではないのでw Close が公開されている場合だけですね。 _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 | ||||||||||||||||
|
投稿日時: 2006-06-12 16:19
私が、理解出来ずに挫折している間にこんなにもレスが・・・・・・。
嬉しいのやら、悲しいのやら・・・・・・。 あれからいろいろ調べ、リソースについてようやく判って来てきました。 それで、Dispose()を試してみたのですが自分の思っていたのと 違う動きをして困惑しています。 Dim dataset1 as dataset 〜〜dataset1に何かセットする〜〜 dataset1.Dispose() dataset1.Dispose()の時点でリソースが開放されdataset1は 参照できなくなると思っていたのですが、 実際はその後の処理の最中にクイックウォッチで値を参照できます。 これはどうゆう状況なのでしょうか? Dispose()はすぐにリソースが開放するという訳ではないのでしょうか? | ||||||||||||||||
|
投稿日時: 2006-06-12 16:44
だーかーらーアンマネージリソースを解放するのと参照できるできないは関係ないってば。 参照できなくなるのはNothing!!おk?? | ||||||||||||||||
|
投稿日時: 2006-06-12 19:55
まずは、「リソース = メモリ」という前提を捨てて下さい。 メモリもリソースですが、Dispose() で解放されるのは「アンマネージリソース」です。 _________________ 囚人のジレンマな日々 | ||||||||||||||||
|
投稿日時: 2006-06-12 20:14
MIRUさん、こんばんは。
例えば以下のような、Dispose しないメソッドを書いて、 2 回続けて呼び出してみて下さい。
| ||||||||||||||||
|
投稿日時: 2006-06-12 21:35
単純に「どちらか」は選べないです。 「そのクラスの終了処理として何が適切か」はクラス仕様が規定します。 Close() と IDisposable.Dispose() が等価でないクラス実装も存在する(存在し得る)ので、「常に選択が可能」と考えるのは良くないと思います。
そです。 例外を throw したクラスインスタンスが、IDisposable.Dispose() 以外の操作を受け付けることを期待していないからです。 受け付ける設計のクラスもあるでしょうが、受け付けないクラスも必ず存在します。 その場合、finally 節内の Close() が例外を発生することも考慮しなくてはならず、コード量が増大します。 しかし、そこまで手当てをしても、どこまで状態が保全できるかは極端な話時の運なので、例外発生後の処理に過度な期待を抱くのはやめて「例外が起きてもアンマネージリソースだけは解放する」というシナリオを選択することにしています。
僕は、なるべく余分な仮定を持ち込まない方針です。
using 句は、隠蔽されている IDisposable.Dispose() も呼び出します。 てか、個人的には IDisposable.Dispose() は「必ず」隠蔽して実装することにしておけば、余分な混乱が避けられたのではないかと思います。 |