- - PR -
継承したコントロールのメモリの解放
投稿者 | 投稿内容 | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2009-02-16 11:07
フィードバックを投げてみるとか。
http://connect.microsoft.com/VisualStudio
作りがダメとは思いませんが、仰るような状況を考えると ・動的に作らずにすむのであれば、動的に作るのをやめる ・インスタンスを使い回しできるのであれば、使い回す など、インスタンスの生成数をなるべく抑えるほうがよいのでしょうね。 | ||||||||||||||||
|
投稿日時: 2009-02-16 11:14
私は .NET の Dispose はあまり良くは知らないのですが、これは Dispose をしたというマークを付けるだけであり、lblTest.Dispose() の次の行に実行が移った時点では、メモリーの解放のようなことがおこなわれるかどうかは保証されないものではないでしょうか。すなわち、ループで回すのでバックログがどんどん溜まるから、メモリー不足になるのではないでしょうか。 また、もし、この時点ですでにメモリーが解放されるとしたら、Dispose のコストが非常に高くなってしまい、現実的ではないと思います。 ループ中に Sleep などで待つようにしても、その内にメモリー不足になるのでしょうか。それかコントロールなので Sleep ぐらいではだめで、一旦、DoEvents 相当のことをしてメッセージポンプが動くようなことも要るのかもしれませんが。 #以下、追記します。 「Dispose をしたというマークを付けるだけ」と書きましたが、この書き方だとちょっと思っていることとニュアンスが違いました。 Dispose メソッドを呼んでも Dispose の処理を開始できるというマークを付けるだけであり、Dispose を開始するかどうかや Dispose が完了するかどうかは保証されないのではないでしょうか、と考えます。 [ メッセージ編集済み 編集者: unibon 編集日時 2009-02-16 11:26 ] | ||||||||||||||||
|
投稿日時: 2009-02-16 13:13
label = nothing の後に Sleep(1) を追加すると、解放されるようですね。 | ||||||||||||||||
|
投稿日時: 2009-02-16 16:33
どちらも違います。 Dispose() メソッドは「クラスインスタンスがカプセルしているアンマネージリソースの解放を行う」ためのメソッドです。 Dispose() メソッドはクラスインスタンス(の構築に使用されるマネージドなメモリ)の破棄をするものではありません。 Dispose() メソッド呼び出しによって何が解放されるのかは、個々のクラス実装に依存します。 ラベルコントロールの場合、Win32 のウィンドウハンドルの解放が行われます。 Label クラスのインスタンス構築に使用されたマネージメモリの解放はGC任せです。 Label クラスに限らず、GCによるマネージドメモリの回収よりも早いペースでインスタンス生成を行えば、メモリ不足となるのは明白です。 | ||||||||||||||||
|
投稿日時: 2009-02-16 16:34
「まじない」ですね。 そもそも label = nothing に意味ないし。 Sleep(1) の引数が 1 で常に期待する効果が得られる保証もありません。 実行環境の CPU 性能やコア数、搭載メモリ量などによってコロコロ変わり得ます。 _________________ // 渋木宏明 (Hiroaki SHIBUKI) // http://hidori.jp/ // Microsoft MVP for Visual C# // // @IT会議室 RSS 配信中: http://hidori.jp/rss/atmarkIT/ | ||||||||||||||||
|
投稿日時: 2009-02-16 22:08
前から気になっていたので質問です。
逆に言い換えれば iniファイル等でパラメタ化しマシン毎に応じた設定を可能とすれば効果があると考えていいのでしょうか? .Netになってメモリ問題に頻繁に遭遇するようになり少々嫌気が指してきているのですが、以前CPU問題やメモリ問題の古典的な対策してSleep処理を思いだし、開発企業に対策を要求したところ2つの案件で成果がありました。 協力会社のやっている事なので詳細報告は求めていませんが、推測としてSleepを入れる事によりGCが動き易くなると考えています。.Netに強制的にGCを実行させるコマンドは無いと聞いています。であればSleep処理は実用的な手段として頭の片隅に置いておいてもいいと思うのですが如何でしょうか? | ||||||||||||||||
|
投稿日時: 2009-02-16 22:46
いいえ。 他プロセスの実行による CPU 負荷やメモリ使用状況などによっても、適切な値は変わるはずなので、静的に値を求めるのは難しいでしょう。
GCの本来の狙いはメモリ管理の煩雑さからプログラマを解放することにあります。 ですが、.NET のGCは一般的なシナリオで高パフォーマンスが得られることを狙った設計になっているため、極端なシナリオではGCが間に合わないケースが起こります。 なので、.NET のGCで不都合を生じるシナリオでは、それに見合った設計が必要です。 実際、高負荷対策として構造体配列を自分で管理して使いまわすようなケースもあります。
逆じゃないかな? メモリ消費のペースが落ちたので、結果としてGCによるメモリ回収が間に合ったんだと思います。 ただ、前回も今回も書きましたが、実行環境によってはまるで効果がないことも十分に考えられる処置です。
いいえ、あります。 GC.Collect() がそれです。 [ メッセージ編集済み 編集者: 渋木宏明(ひどり) 編集日時 2009-02-16 22:47 ] [ メッセージ編集済み 編集者: 渋木宏明(ひどり) 編集日時 2009-02-16 22:52 ] | ||||||||||||||||
|
投稿日時: 2009-02-16 22:55
参考と言うことでリンクを張っておきます。
http://msdn.microsoft.com/ja-jp/library/system.gc_members.aspx ファイナライザの完了を待つとかも一応あります。 |