1

確かにこの質問は以前に尋ねられたことがありますが、これに関するスレッドが見つからなかったので、回答済みの質問へのリンクも役立ちます。

スライス(Slice)の配列を含むボリュームクラス(VoxelVolume)があります。

public class VoxelVolume
{
    Slice[] mySlices;

    public VoxelVolume(int noOfSlices)
    {
        mySlices = new Slice[noOfSlices];

        for (int i = 0; i < mySlices.Length; i++)
        {
            mySlices[i] = new Slice(this);
        }
    }
}

ボリュームはスライスを認識し、スライスはボリュームを認識します。

public class Slice
{
    public VoxelVolume Volume
    {
        get;
        private set;
    }

    public Slice(VoxelVolume aVolume)
    {
        Volume = aVolume;
    }
}

問題は、相互にオブジェクトを参照しているため、ボリュームがガベージコレクションされないことです。そのため、スライスからボリュームへの参照をWeakReferenceとして実装しました。

public class Slice
{
    WeakReference myVolume;

    VoxelVolume Volume
    {
        get
        {
            return (VoxelVolume)myVolume.Target;
        }
    }

    public Slice(VoxelVolume aVolume)
    {
        myVolume = new WeakReference(aVolume);
    }
}

これでガベージコレクションが機能しますが、追加のWeakReferenceを使用します。何千ものスライスを持つことができるので、WeakReferencesの労力は非常に高くなります。

編集:最初は表示されませんでしたが、大量のメモリを使用しているため、「メモリリーク」が発生しました。したがって、JetBrains dotTraceを使用して、参照されているオブジェクトと使用可能なオブジェクトを調べました。使用されなくなったものの、多くのオブジェクトが利用可能であることがわかりました。前に言ったように、WeakReferenceを使用すると問題が解決しました。

問題は、TreeNodeもTreeViewの知識を持っているため、TreeViewがこれらの問題をどのように解決するかということです。

これに対する適切な解決策を知っていますか?

ありがとうマーティン

4

2 に答える 2

3

問題は、相互にオブジェクトを参照しているため、ボリュームがガベージコレクションされないことです。

これは、何かSliceがまたはのいずれかにアクセスできる場合にのみ問題になりVoxelVolumeます。どちらのオブジェクトへの参照もなくなると、両方ともガベージコレクションの対象になります。オブジェクトのサイクルは、参照カウントを使用しないため、.NETでは問題になりません。

もちろん、 GCルートからSliceまたはのいずれかへの参照がないことを確認する必要があります。VoxelVolumeここで何が起こっているのかを知るのに十分なコンテキストを私たちに与えていないのです。

于 2012-07-23T07:26:22.647 に答える
0

CLR の GC エンジンは、他の誰も参照していない限り、循環参照オブジェクトを収集する必要があります。

また、IDisposable パターンを実装し、不要になったときに参照をクリアすることもお勧めします。気付かなかった何か悪い参照が保持された場合に、大量のメモリリークの可能性を減らすことができます。

于 2012-07-23T07:27:40.610 に答える