- PR -

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

投稿者投稿内容
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2006-06-10 20:16
引用:

MIRUさんの書き込み (2006-06-09 20:08) より:
あと、sessionの開放についても思うところがあるのですが、
session.Clear     と
session(〜)=nothing
では開放の仕方が違うのでしょうか?

その後の、クイックウォッチで値を見ると
Clearは""、nothingはnothingとなっています。


何を見てそう出たんですか?(特にClearの方)
開放の仕方もなにも、それぞれ目的も意味も違いますよね?
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2006-06-10 20:37
全般的に短絡的に言葉だけで理解しようとしすぎです。
※状況、使い方によってさまざまなので一概には言えません。

>・nothingは参照できなくなるだけでメモリ管理上での意味はほとんど無い
Nothingの代入は、メモリ管理上で意味があります。
ただし状況によってほとんど意味が無い(結果的に変わらない)こともあるし、
重要な意味を持つ場合もあります。
Nothingはどうこうと一言で決められるものではありません。

>・PostBackが起こったときは、各変数は参照が出来なくなる(nothingと同じ)
Pageのインスタンスは、ページ生成の処理(1リクエストの処理)が完了すれば
破棄されます。
PostBack時に削除されるのではなくて、1リクエスト完了の時点で破棄されます。
PostBack時には、既に前回のPageインスタンスは参照できなくなっています。
また既にGCで回収済みかもしれません。

>・GCに任せず出来るだけ早くメモリを空けたいときは、Dispose() を使う
早くメモリを開放したい場合にDisposeなんて誰も言ってません。
※ていうか、皆さん仰っているようにDisposeとメモリは「基本的には」関係ありません。

>・session.Clear()はちゃんと削除(メモリ領域の開放)を行っている
>・session(〜)=nothing はやっぱりメモリ管理上意味は無い
Session.Clearはセッション変数を全部削除(開放)します。

Session(〜)=Nothingでは、対象のセッション変数にNothingをセットしています。
もし対象のセッション変数に既に何かが格納されていたのなら「結果的に」
そのセッション変数に格納されていたオブジェクトは開放されます。
まあ普通消したい場合はRemoveを使います。
Nothingの代入でも大差はありませんが、セッション変数(名前を付けた入れ物)自体は
残っているイメージです(ただし中身はNothingなのでオブジェクトが残っているわけではない)。
※Session.Countなどで個数を数えると違いが分かります。

Nothingの代入をした場合としてない場合では、当然もとももと格納されていた
オブジェクトが開放されるかそのままかという違いがあるので、メモリ管理上も
違いは大ありです。
MIRU
常連さん
会議室デビュー日: 2006/05/30
投稿数: 21
投稿日時: 2006-06-11 18:18
正直、皆さんの回答の半分ぐらいしか理解できない状態です。(特にDispose()… )
どうやら私は、まだこの質問をしていい段階にきていなかったようです。

皆さんの回答を元に、もう少し自分なりに調べてみます。
ありがとうございました。
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2006-06-11 20:53
引用:

MIRUさんの書き込み (2006-06-11 18:18) より:

正直、皆さんの回答の半分ぐらいしか理解できない状態です。(特にDispose()… )
どうやら私は、まだこの質問をしていい段階にきていなかったようです。


質問していい段階とかそんなものは無いのでご安心を
できれば、ここで理解を深めていってほしいですね

Dispose() ですが、データベースからデータを検索するときは
どんなコードを記述していますか?
コネクションの部分にだけ注目して記述すると次のようになると思います。
using を使うべきですがはしょります。
コード:

OleDbConnection conn = new OleDbConnection(connString);
conn.Open();
conn.Close();
conn.Dispose();


Close() で現在開いているDBコネクションを閉じます。
ただし、この段階ではDBコネクション自体は conn に保持さたままです。
(つまりいつ開放されるかわからない)

けれど DBコネクション は限りの有る資源なので
できるだけ短い間に開放したいと思うはずです。
OleDbConnection の Dispose() は他の人が使用できるように
コネクションを開放する作業を行ってくれます。

conn のメモリがいつ開放されるのかはわからないけれど
とりあえず他の人のためにアンマネージリソース(DBコネクション)は
開放しときますねっていうものでしょうか

[ メッセージ編集済み 編集者: かるあ 編集日時 2006-06-11 20:54 ]
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2006-06-11 21:50
引用:

かるあさんの書き込み (2006-06-11 20:53) より:
Close() で現在開いているDBコネクションを閉じます。
ただし、この段階ではDBコネクション自体は conn に保持さたままです。
(つまりいつ開放されるかわからない)

けれど DBコネクション は限りの有る資源なので
できるだけ短い間に開放したいと思うはずです。
OleDbConnection の Dispose() は他の人が使用できるように
コネクションを開放する作業を行ってくれます。

conn のメモリがいつ開放されるのかはわからないけれど
とりあえず他の人のためにアンマネージリソース(DBコネクション)は
開放しときますねっていうものでしょうか


Closeでコネクションのリソースは開放されます。

Disposeは実質的には必須ではありませんが、
オブジェクトの使用を終了したということを明示するのと、
usingやfinallyなど保険的な後始末の意味合いの場所で
Disposeしておくのがまあ一般的ですかね。
このへんは人によって違いそうですが。
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2006-06-11 22:07
引用:

なちゃさんの書き込み (2006-06-11 21:50) より:

Closeでコネクションのリソースは開放されます。


えっ!!そうなんですか!?

もうかなり昔(2年半ぐらい前)ですが ODP.NET で Close を発行しても
ピーク時に最大コネクション数を超えてしまって困ったことがありました。
この時は Close の後に Dispose を呼び出すようにして解決したことがあったので
そういうものだと思っていたんですが…(汗
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-06-12 06:53
引用:

かるあさんの書き込み (2006-06-11 22:07) より:

えっ!!そうなんですか!?


~Connection 系に限って言えば、アンマネージ リソース "は"、解放するでしょう。

そのほか、
 「Close and Dispose are functionally equivalent...」
などと、リファレンスに書かれているクラスは解放されるでしょう。

~Connection や Stream 系に限って言えば、Close / Dispose した後に、
Open ができるか / Open ができないか、などの違いがあるものもあります。

どちらにしても 「アンマネージ リソース」 自体は解放されていて、
そのままのインスタンスで、再オープンできるかどうかの違いでしかないです。

# 全部がそうである保証はないので、どちらか一方を選ぶなら IDispose.Dispose メソッドでしょう。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2006-06-12 08:40
引用:

# 全部がそうである保証はないので、どちらか一方を選ぶなら IDispose.Dispose メソッドでしょう。



機械的に選んじゃ駄目です。

Close() があるなら Close() が正当な終了処理で、IDisposable.Dispose() は fail safe 出しかない場合もあります。

クラスの仕様をドキュメントで確認して、適切な方法で終了処理を行いましょう。

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