9/13/2009

VB.NET における メモリリーク問題

どうもJudaです。
最近はTwitterでつぶやきまくって、満足しているのですが、それではここの利用価値が上がらないので、割と重めな内容をPickUp

VB.NETで長時間運用するとメモリを圧迫してメモリリークを起こす問題がある。
http://support.microsoft.com/default.aspx?scid=kb;[ln];q313417
大学時代の製作物の中にこの問題にひっかかるものがあるので、コレに対処するべく調査中。

開発者として給料をいただいている身で思うことがある。
それは、プログラマに求められる以上のことだ。
自己を防衛するための機構の導入だ。
テストしかり、トレースしかり、デバッグプリントしかり、ログ機能しかり。
これらのものは、本来の開発ではオプションである。
しかしこれらを欠くと著しく後期の開発において欠損を生む。
近頃これをよく思う。

詳しくは後日説明を加えたいと思う。


それで後日談。
とりあえず.NETのガベージコレクタはそれほど賢くないので、なるべく明確にゴミを設定してやる必要がある。

それとその前に結果的にだが、プログラマはオブジェクトの所有権にその持ち方についてある程度留意する必要があるということだ。(スマートなポインタが売りだった気がするのだが。

結論としてDisposeのメソッドをもつことが最も確実なメモリ解放への配慮だったりする。
いくつかあるメモリへの配慮として、

  • 変数にNothingをSetする。

  • 配列をEraseする。


ちなみに配列のEraseはすべての要素にNothingを入れるのとほぼ同等らしいです。

ここからが問題ですが、クラスの確保した領域の解放ですが、ここはさりげなくC/C++とそれほど変わらないというのが調べてみた感じです。

  • 循環参照はうまく解決できない。

  • Nothingを入れる前に入っている変数のサイズ分しか解放されないっぽい。


これは確かC/C++でmallocを行ったときに発生するプログラマのぼんやりから発生するメモリリークとそれほど変わらない。結局C/C++的な考え方を持ち込んでこないと問題を回避できないっぽい。
ここで、明確に破棄するための手段としてIDisposeの適応が考えられる。これによってプログラマは明示的に破棄方法を設定できる。これがもっとも問題の少ない解決法である。

これは憶測だが、Stringの解放が若干怪しい気がするが、基本型で用意されているので問題ないと思うが、C/C++的な考え方からするとこれは基本型ではないので、ちゃんと解放されるのか心配だ。

0 件のコメント:

コメントを投稿