DOBON.NET DOBON.NETプログラミング掲示板過去ログ

オブジェクトの解放

分類:[.NET]

.NETではガベージコレクションというメモリを自動的に検出し解放してくれる機能があるのは
分かりました。ただ、オブジェクトによってはDisposeメソッドでこちらで明示的に記述して解放した
方がよいものもありますが、Disposeメソッドのないオブジェクトも多々あることが分かりました。
Dispose、またはCloseのような解放やオブジェクトを閉じるメソッドをユーザーが記述できないものに関し
ては、本当にこちらで何もしなくても良いのでしょうか?
今まではVBばかり使っていたので、Newによりオブジェクトを生成したら、必ず解放していたので
疑問に感じまして。パフォーマンスが悪くなるということは本当におきないのでしょうか・・・
素人じみた質問ですみません。
  • 題名: Re[1]: オブジェクトの解放
  • 著者: よねKEN
  • 日時: 2003/11/27 11:39:58
  • ID: 1607
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
2003/11/27(Thu) 11:44:00 編集(投稿者)

> .NETではガベージコレクションというメモリを自動的に検出し解放してくれる機能があるのは分かりました。

どこからも参照されていないオブジェクトがガベージコレクションで
自動解放される候補になります。
なので、ガベージコレクションで掃除してもらうために、オブジェクトが不要に
なったら参照を解放するのはプログラマの責任になります。

参照を解放するというのは、
Dim a As ClassA
a = New ClassA
のようにしてClassAのインスタンスを生成し、その参照を変数aが保持している状態から、
a = Nothing
としてインスタンスへの参照している変数にNothingを設定して解放してやる作業です。

ただし、下記のMethodAの例のようにメソッド内で定義しているローカル変数は、
メソッドを抜ける時点でNothingに設定されるので自分でNothingを設定してやる必要はありません。

(例1)
Class ClassB
Public Sub MethodA()
Dim a As ClassA
a = New ClassA
' 何かの処理
'a = Nothing ' この作業は不要
End Sub
End Class

しかし、下記のような例の場合で、一回MethodAを呼び出すと
変数aにClassAのインスタンスへの参照が設定されますので、
このインスタンスが不要になった時点でNothingを設定しないと
ClassBのインスタンスがガベージコレクトされるまで、
内部で変数aが参照しているClassAインスタンスはガベージコレクションの対象になりません。
ReleaseAメソッドを呼ぶと変数aにNothingを設定するので、ガベージコレクションの対象になります。

(例2)
Class ClassB
Private a As ClassA

Public Sub MethodA()
a = New ClassA
End Sub

Public Sub ReleaseA()
a = Nothing ' ClassBのインスタンスを破棄しないで、
' 変数aの参照しているClassAインスタンスをガベージコレクション
' の対象にするには変数aにNothingを設定する必要がある。
End Sub
End Class

> ただ、オブジェクトによってはDisposeメソッドでこちらで明示的に記述して解放した
> 方がよいものもありますが、Disposeメソッドのないオブジェクトも多々あることが分かりました。
> Dispose、またはCloseのような解放やオブジェクトを閉じるメソッドをユーザーが記述できないものに関し
> ては、本当にこちらで何もしなくても良いのでしょうか?

参照を保持している変数が存在しない状態にさえなっていればOKです。

> 今まではVBばかり使っていたので、Newによりオブジェクトを生成したら、必ず解放していたので

プログラマが行うべき責任は旧VBでもVB.NETでも基本的に同じで、
インスタンスが不要になったら、そのインスタンスへの参照を保持している変数が
ないようにする責任があるだけです。

その後のメモリの扱われ方はVBとVB.NETで動作が異なりますが、
これは元々プログラマが意識する必要は(あまり)ないところなので関係ないですし。

DOBON.NET | プログラミング道 | プログラミング掲示板