アプリ版:「スタンプのみでお礼する」機能のリリースについて

メモリが解放されずに残るケースというのは、どういうときがあるのでしょうか?
※asp.netでプログラムを書いています。

(1)どのクラスも、基本的にコンストラクタでメモリが確保され、
どのクラスも、その親のオブジェクトが解放されたら、自分自身のメモリも解放される。
よって、画面のCloseで、すべてのオブジェクトのメモリは解放される。と思っています。

(2)スタティックメソッドで、参照渡しの引数があるとき、何度そのメソッドを使っても、
オブジェクトのポイントが渡るだけだし、処理完了後は、そのポインタすらも解放すると思っています。

(3)画面右上の「×」のボタン以外で画面が閉じてしまったとしても、セッションタイムアウトになった時点で、その分のメモリは解放すると思っています。

◆どうしてdisposeメソッドがあるのでしょうか?
.自分は、プログラム内に1箇所もdisposeを書く必要がないと思っていますが、どのような時に使うべきなのでしょうか?

A 回答 (3件)

メモリの確保はnew演算子のタイミングです (コンストラクタではありません)。


staticなフィールドに関しては,別のタイミングになります。

また,解放されるのは,
・そのインスタンスへの全てのルート参照から(強)参照で辿るためのパスが存在しない
・該当世代のガベージコレクションが実行された
の両方を満たすタイミングです。
# ファイナライザがあると,解放が1世代遅れます。

で,staticなフィールドはルート参照であり,そこから(強)参照で辿れるインスタンスは,解放されることがありません。
クラスTのstaticなフィールドにList<T>を用意し,TのコンストラクタでそのフィールドにthisをAddしているような場合に相当します。
staticなフィールドから辿れるインスタンスは,明示的にListからRemoveするなり,nullを代入するなりして,参照を辿れなくする必要があります。
ASP.NETにおけるメモリリークは,これが一番の原因になると思います。


IDisposable.Disposeメソッドは,インスタンスの後処理を行うためのメソッドです。
主に,メモリ以外のリソースの解放処理を行います。
ファイルやネットワーク,DBコネクションなどはGCのタイミングで解放されたのでは遅いことが多いため,Disposeを呼び出します。
なお,通常はusing文を使ってIDisposable.Disposeを確実に呼び出すことが出来るようにします。
    • good
    • 0
この回答へのお礼

try...finallyよりも、usingの方がシンプルなソースになるので、そっちを調べてみました。

◆ファイル,ネットワーク,DBコネクションなどのときは、
Dim s As String
Using sr As New System.IO.StreamReader( _
"C:\test.txt", System.Text.Encoding.GetEncoding(932))
s = sr.ReadToEnd()
End Using

Console.WriteLine(s)

のようにしようと思います。
ありがとうございます!

お礼日時:2013/03/20 20:55

(1)「その親のオブジェクトが解放されたら」と書かれていますが、その親のオブジェクトが解放されるのはいつですか。


(2)解放されるタイミングは処理完了後ではありません。
(3)ASP.NETならクライアント側の画面は関係ありません。

この回答への補足

(1),(2)
親オブジェクトが、
ApplicationStartでnewされたなら、生きているのはApplicationEndまででしょうし、
SessionStartでnewされたものは、生きているのはSessionEndまででしょうし、
画面が開かれた際に作られる、画面上のオブジェクトは、画面が閉じられるまでという認識です。
画面のCloseが適正にハンドルできなかった場合などは、SessionTimeOutで消えると思っています。

補足日時:2013/03/20 20:32
    • good
    • 0
この回答へのお礼

調べる良いきっかけになりました。ありがとうございます。

お礼日時:2013/03/20 21:01

.NET アプリのランタイムにはガベージコレクタが備わっているので、サーバー側ではメモリリークよりコネクションリークが問題になると思います。

詳しくは以下のページを参照してください。Dispose メソッドについても書かれています。

.NETの例外処理 Part.2
http://blogs.msdn.com/b/nakama/archive/2009/01/0 …

ブラウザ側では循環参照がメモリーリークの原因として一番多いのではないかと思います。詳しくは以下のページを見てください。

Internet Explorer リーク パターンを理解して解決する
http://msdn.microsoft.com/ja-jp/library/bb250448 …
    • good
    • 0
この回答へのお礼

ガベージコレクタ様々ですね。
メモリ以外のリソースの割り当てと管理は、usingで行おうと思います。
ブラウザ側は、単純にデータを表示しているだけなので、今回は問題なさそうです。

ありがとうございます。

お礼日時:2013/03/20 21:00

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!