- PR -

継承したコントロールのメモリの解放

投稿者投稿内容
セラフ
ベテラン
会議室デビュー日: 2005/12/01
投稿数: 95
お住まい・勤務地: 東北の顔の形といえば
投稿日時: 2009-01-20 16:47
他人のブログなので若干気が引けますが、日本語としてまとまった記事が見つからなかったので・・・
http://salv.miscnotes.com/2008/01/net_framework.php

それは置いといて、ミニマムソース試してみましたが、本当ですね〜。
全然気づきませんでした。いろいろいじってみましたが、一向に開放される様子がありません。これはバグの可能性がありますね・・・。
KT工房
常連さん
会議室デビュー日: 2006/06/20
投稿数: 49
投稿日時: 2009-01-21 09:38
セラフさんコメントありがとうございます。
やはりバグなんでしょうかね?
パフォーマンスモニタで見るとジェネレーション2のメモリが増えていました。
なので、解放対象となっていないようです。

VS2008でも同様の現象がでました。
そもそもインスタンスを大量に生成するような作りがまずいんでしょうかねぇ・・・?
そんなにクリティカルな条件では無いと思うのですが?

よこけん
大ベテラン
会議室デビュー日: 2006/01/31
投稿数: 216
投稿日時: 2009-01-21 10:06
これ、Release モードだと発生しませんね。
_________________
C#と諸々
よこけん
大ベテラン
会議室デビュー日: 2006/01/31
投稿数: 216
投稿日時: 2009-01-21 10:26
もう一点。
デバッグ実行時でも、回収自体は行われているようです。

コード:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Dim weakReferences As New List(Of WeakReference)()

    For i As Integer = 0 To 1000000
        Dim xLeak As CustomDataSet

        xLeak = New CustomDataSet
        weakReferences.Add(New WeakReference(xLeak))
        xLeak.Dispose()
        xLeak = Nothing
    Next

    GC.Collect()

    Dim count As Integer = 0
    For Each item As WeakReference In weakReferences
        If (item.IsAlive) Then
            count += 1
        End If
    Next
    MessageBox.Show(count)

End Sub




_________________
C#と諸々
KT工房
常連さん
会議室デビュー日: 2006/06/20
投稿数: 49
投稿日時: 2009-01-21 10:50
よこけんさんコメントありがとうございます。

一応昨日から、継承したDataSetを使わずに通常のDataSetを使うように変更したら
今のところはメモリの上昇は見られませんでした。

リリースモードとは全然考えていませんでした。
早速試してみたいと思います。
KT工房
常連さん
会議室デビュー日: 2006/06/20
投稿数: 49
投稿日時: 2009-01-27 13:19
とりあえず調査報告です。
メモリが解放されない要因としては、以下の項目が関係しているようです。

最適化が有効であれば、メモリが解放される
(リリースモードはデフォルトで最適化が有効となっている)

デバッグモードでも最適化を有効にすればメモリが解放された。
逆にリリースモードでも最適化を無効にするとメモリが解放されない。

最適化により何が行われているのがわかりませんが、
この現象が解決しない限り、最適化無効で作ったDLLは使い物にならないような気がします。
必ず最適化有効でコンパイルすればよいのですが、忘れてしまうこともありますし・・・。
KT工房
常連さん
会議室デビュー日: 2006/06/20
投稿数: 49
投稿日時: 2009-02-02 13:28
さらに調査報告です。
コンパイルオプションも、継承も関係なしに通常のコントロールでも
生成→解放を繰り返すと Out of Memory Exception で落ちることを確認しました。
2G超える前ぐらい?

実メモリに変動は無いのですが、ワーカーセットのメモリが増加していきます。

サンプルソースは以下です。

Dim lblTest as Label

For i as Integer = 1 to 10000000
lblTest = New Label()
lblTest.Dispose()
lblTest = Nothing
Next

メモリ増加の確認はタスクマネージャでも行えます。
1生成あたり4Byte程度増えているようです。

そもそもこういった使い方が間違いなんでしょうか?
環境によるものだと良いのですが・・・。

解決策が無い場合、今後.Netの使うのに不安になりますね。
KT工房
常連さん
会議室デビュー日: 2006/06/20
投稿数: 49
投稿日時: 2009-02-16 10:48
どうにも反応が無いですね、寂しい限りです(笑)

やはり動的にコントロールを作成するという作りがダメなんでしょうか?
それとも多少リーク?してもメモリの許容範囲内だから放置なんでしょうか?
でも、直せるなら直したいですよね(T〜T;

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