- PR -

変数に対するメモリの使い方について

投稿者投稿内容
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2006-06-12 12:56
Dispose の実装はそれぞれ違いがあるから気をつけなければいけない
っていうことでしょうか。
とりあえず IDispose を実装していれば using または try...finally を使って
破棄を確実にしてあげることが大切なんですよね。

Oracle.DataAccess.Client.OracleConnection
の場合こんな記述がありました。
引用:

切断時の記述は以下のとおりDispose() メソッドを実行します。Close() メソッドだけでは明示的に接続が解放されず、.NET Framework の共通言語ランタイム(CLR)によるガベージコレクタによってクラスが開放されることではじめて切断される動作になります。安全なプログラムを作成するという観点から明示的にDispose するべきです。


http://otndnld.oracle.co.jp/beginner/odpnet/2_1/index.html
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2006-06-12 14:04
引用:

Dispose の実装はそれぞれ違いがあるから気をつけなければいけない
っていうことでしょうか。



決定論的な実装指針が示されていないので、一般論としてはそういうことになります。

引用:

とりあえず IDispose を実装していれば using または try...finally を使って
破棄を確実にしてあげることが大切なんですよね。



IDisposable.Dispose() を確実に呼び出すことで、「最悪の場合」でもアンマネージリソースが解放され、アンマネージリソースの解放漏れによる問題を回避することが出来ます。

ただし、IDisposable.Dispose() 呼び出しによって「アンマネージリソース解放以外の終了処理」がすべて正常に行われる保証は無い(=少なくとも IDisposable.Dispose() の定義はそれを求めていない)ので、Close() 呼び出しをサボって IDisposable.Dispose() 呼び出しのみを行った場合、クラス実装によっては何らかの喜ばしくない副作用があるかもしれません。

これは、IDisposable.Dispose() 云々というよりは、クラス設計・実装の問題です。

引用:

Oracle.DataAccess.Client.OracleConnection
の場合こんな記述がありました。



うれしくない実装ですね ;-p
何か勘違いしてるとしか思えない。。。

じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-06-12 16:11
引用:

渋木宏明(ひどり)さんの書き込み (2006-06-12 08:40) より:

機械的に選んじゃ駄目です。
Close() があるなら Close() が正当な終了処理で、IDisposable.Dispose() は fail safe 出しかない場合もあります。
クラスの仕様をドキュメントで確認して、適切な方法で終了処理を行いましょう。


究極的な話、どちらかを選ぶならです。

私自身は Using と Try 〜 Finally + Close で入れ子にしています。
ひどりさんは、Close メソッドは正常処理としてなので Finally での実装はしない、でしたよね?

このあたりの指針は、人によって若干異なりますね。
IDisposable.Dispose メソッドが、隠蔽されていても呼ぶ なんて流派もいますね。
私は、そこまで過激派ではないのでw Close が公開されている場合だけですね。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
MIRU
常連さん
会議室デビュー日: 2006/05/30
投稿数: 21
投稿日時: 2006-06-12 16:19
私が、理解出来ずに挫折している間にこんなにもレスが・・・・・・。
嬉しいのやら、悲しいのやら・・・・・・。

あれからいろいろ調べ、リソースについてようやく判って来てきました。

それで、Dispose()を試してみたのですが自分の思っていたのと
違う動きをして困惑しています。

Dim dataset1 as dataset
〜〜dataset1に何かセットする〜〜
dataset1.Dispose()

dataset1.Dispose()の時点でリソースが開放されdataset1は
参照できなくなると思っていたのですが、
実際はその後の処理の最中にクイックウォッチで値を参照できます。

これはどうゆう状況なのでしょうか?
Dispose()はすぐにリソースが開放するという訳ではないのでしょうか?
ぶさいくろう
ぬし
会議室デビュー日: 2005/11/22
投稿数: 1232
お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
投稿日時: 2006-06-12 16:44
引用:

MIRUさんの書き込み (2006-06-12 16:19) より:
Dispose()はすぐにリソースが開放するという訳ではないのでしょうか?


だーかーらーアンマネージリソースを解放するのと参照できるできないは関係ないってば。
参照できなくなるのはNothing!!おk??
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2006-06-12 19:55
引用:

これはどうゆう状況なのでしょうか?
Dispose()はすぐにリソースが開放するという訳ではないのでしょうか?


まずは、「リソース = メモリ」という前提を捨てて下さい。
メモリもリソースですが、Dispose() で解放されるのは「アンマネージリソース」です。
_________________
囚人のジレンマな日々
きくちゃん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 854
お住まい・勤務地: 都内某所
投稿日時: 2006-06-12 20:14
MIRUさん、こんばんは。

引用:

Dispose()はすぐにリソースが開放するという訳ではないのでしょうか?



例えば以下のような、Dispose しないメソッドを書いて、 2 回続けて呼び出してみて下さい。

コード:
Private Sub Hoge
    Dim MyFile As System.IO.FileStream = System.IO.File.Open("c:¥hoge.txt", _
        IO.FileMode.Create, IO.FileAccess.ReadWrite, IO.FileShare.None)
    ' MyFile.Dispose() ' Dispose しない。
End Sub


渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2006-06-12 21:35
引用:

究極的な話、どちらかを選ぶならです。



単純に「どちらか」は選べないです。
「そのクラスの終了処理として何が適切か」はクラス仕様が規定します。

Close() と IDisposable.Dispose() が等価でないクラス実装も存在する(存在し得る)ので、「常に選択が可能」と考えるのは良くないと思います。

引用:

私自身は Using と Try 〜 Finally + Close で入れ子にしています。
ひどりさんは、Close メソッドは正常処理としてなので Finally での実装はしない、でしたよね?



そです。
例外を throw したクラスインスタンスが、IDisposable.Dispose() 以外の操作を受け付けることを期待していないからです。

受け付ける設計のクラスもあるでしょうが、受け付けないクラスも必ず存在します。
その場合、finally 節内の Close() が例外を発生することも考慮しなくてはならず、コード量が増大します。

しかし、そこまで手当てをしても、どこまで状態が保全できるかは極端な話時の運なので、例外発生後の処理に過度な期待を抱くのはやめて「例外が起きてもアンマネージリソースだけは解放する」というシナリオを選択することにしています。

引用:

このあたりの指針は、人によって若干異なりますね。



僕は、なるべく余分な仮定を持ち込まない方針です。

引用:

IDisposable.Dispose メソッドが、隠蔽されていても呼ぶ なんて流派もいますね。



using 句は、隠蔽されている IDisposable.Dispose() も呼び出します。

てか、個人的には IDisposable.Dispose() は「必ず」隠蔽して実装することにしておけば、余分な混乱が避けられたのではないかと思います。

スキルアップ/キャリアアップ(JOB@IT)