4

com-wrapper を継続的にインスタンス化し、GC に (強制ではなく) 収集させると、奇妙な現象が発生します。

WinCE x86 の .net cf でこれをテストしています。.net Compact フレームワークのリモート モニターでパフォーマンスを監視します。ネイティブ メモリは、プラットフォーム ビルダー ツールキットの Windows CE リモート パフォーマンス モニターで追跡されます。

最初の 1000 個の作成されたインスタンスの間、perfmon のすべてのカウンターは正常に見えます。

  • GC ヒープは増減しますが、平均は変わりません
  • ピン留めされたオブジェクトは 0 です
  • ネイティブメモリは同じ平均を維持します
  • ...

ただし、これらの 1000 (およそ) の後、ピン留めされたオブジェクト カウンターは上昇し、カウントが減少することはありません。ただし、メモリ使用量は同じままです。

この情報からどのような結論を引き出すべきかわかりません... これはカウンターのバグですか、これは私のソフトウェアのバグですか?

[編集]

コンパクターによって移動されていないオブジェクトと同様に、GC が安定した後に使用中の合計バイト数がすぐに増加し始めることに気付きました。

カウンターのグラフィック http://files.stormenet.be/gc_pinnedobj.jpg

[/編集]

関連するコードは次のとおりです。

    private void pButton6_Click(object sender, EventArgs e) {
        if (_running) {
            _running = false;
            return;
        }
        _loopcount = 0;
        _running = true;

        Thread d = new Thread(new ThreadStart(LoopRun));
        d.Start();
    }

    private void LoopRun() {
        while (_running) {
            CreateInstances();
            _loopcount++;
            RefreshLabel();
        }
    }

    void CreateInstances() {
        List<Ppb.Drawing.Image> list = new List<Ppb.Drawing.Image>();
        for (int i = 0; i < 10; i++) {
            Ppb.Drawing.Image g = resourcesObj.someBitmap;
            list.Add(g);
        }

    }

Image オブジェクトには AlphaImage が含まれています。

    public sealed class AlphaImage : IDisposable {
    IImage _image;
    Size _size;
    IntPtr _bufferPtr;

    public static AlphaImage CreateFromBuffer(byte[] buffer, long size) {
        AlphaImage instance = new AlphaImage();
        IImage img;
        instance._bufferPtr = Marshal.AllocHGlobal((int)size);
        Marshal.Copy(buffer, 0, instance._bufferPtr, (int)size);
        GetIImagingFactory().CreateImageFromBuffer(instance._bufferPtr, (uint)size, BufferDisposalFlag.BufferDisposalFlagGlobalFree, out img);
        instance.SetImage(img);
        return instance;
    }

    void SetImage(IImage image) {
        _image = image;
        ImageInfo imgInfo;
        _image.GetImageInfo(out imgInfo);
        _size = new Size((int)imgInfo.Width, (int)imgInfo.Height);
    }

    ~AlphaImage() {
        Dispose();
    }

    #region IDisposable Members

    public void Dispose() {
        Marshal.FinalReleaseComObject(_image);
    }
}
4

2 に答える 2

4

多くの IDisposable インスタンスを作成し、それらに対して Dispose を呼び出していないという点で、コードにバグがあります。ファイナライザーが最終的に機能することを願っていますが、実際には必要ないはずです。プロダクション コードでは、すべてを適切に破棄していますか? そうでない場合、それができない理由はありますか?

AlphaImage ファイナライザーにログを記録すると (AppDomain のアンロードとアプリケーションのシャットダウンを検出し、それらの場合はログに記録されません!)、ファイナライザーが呼び出されていることが示されますか?

編集:おそらくあなたを悩ませているわけではありませんが、とにかく修正する価値があるかもしれない潜在的な問題の1つ-CreateImageFromBufferの呼び出しが何らかの理由で失敗した場合、AllocHGlobalによって作成されたメモリをまだ所有しており、現在リークされています. それは問題ではないか、もっと壮観に爆発するのではないかと思いますが、考える価値はあります。

于 2008-12-17T10:59:57.703 に答える
3

RPMのバグではないかと思います。ここにないのは、Ppb.Drawingに関する洞察です。潜在的な問題が発生する可能性があるのは、GetIImagingFactory呼び出しです。それは何をするためのものか?おそらくシングルトンゲッターですが、私が追いかけたいものです。

AllochHGlobalも表示されますが、割り当てが解放されるのはどこにも表示されません。今のところ、それが私が焦点を当てるところです。

于 2008-12-17T12:19:57.417 に答える