2

次の画像のサイズ変更と保存コードがあります。

このコードは、ASP.NET MVC プロジェクトの別のスレッドで実行されます。として

using (FileStream fs = new FileStream(file.File.FullName, 
                FileMode.Open, FileAccess.Read, FileShare.Read))
{
    BitmapDecoder decoder = BitmapDecoder.Create(fs, 
          BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None);

    var img = decoder.Frames[0];
    img.Freeze();
    double width = Size;
    double height = Size;

    if (img.PixelWidth > img.PixelHeight)
    {
        height = (int)(((double)img.PixelHeight / (double)img.PixelWidth) 
           * (double)width);
    }
    else
    {
        width = (int)(((double)img.PixelWidth / (double)img.PixelHeight) 
           * (double)height);
    }

    var target = new TransformedBitmap(img,
        new ScaleTransform(width / (double)img.PixelWidth, height 
                / (double)img.PixelHeight, 0, 0));

    RenderOptions.SetBitmapScalingMode(target, BitmapScalingMode.HighQuality);

    var t = BitmapFrame.Create(target);
    RenderOptions.SetBitmapScalingMode(t, BitmapScalingMode.HighQuality);

    target.Freeze();
    t.Freeze();
    JpegBitmapEncoder enc = new JpegBitmapEncoder();
    enc.Frames.Add(t);
    enc.QualityLevel = 90;
    using (FileStream fsout = saved.File.OpenWrite())
    {
        enc.Save(fsout);
    }
}

私はすべての IDisposable オブジェクトを使用してきましたが、WPF オブジェクトは IDisposable を実装していないため、手動で破棄することはできません。

Freeze を呼び出すとメモリ リークが防止されるとどこかで読みましたが、その後も改善されません。このプロセスのメモリ使用量は増え続けています。

私が必要とするのは、画像がアップロードされたときに、150x150、350x350、700x700、および 1000x1000 の 4 つの異なる解像度でサイズ変更する必要があることです。これらの解像度のそれぞれは、Parallel.ForEach メソッドを使用して並列に呼び出されます。

私のウェブサイトの残りの部分は、Entity Framework を使用した単なる単純なデータベース アクセスです。これにより、最大 3 GB のメモリ使用量でメモリ リークが発生する可能性はありません。

4

1 に答える 1

1

これをスタンドアロンのテスト プログラムのループに入れて、関数の後に明示的な GC.Collect() を追加してみました。少なくとも .NET 4.5 では、これはこのコードがリークしないことを示しています。多くの呼び出しの後、メモリは安定したままです。

コードの他の場所を探す必要があると思います。[分析] > [パフォーマンス ウィザードの起動...] でプロファイリングを試み、[.NET メモリ割り当て] を選択して、何がメモリを使用しているかを確認してください。

楽しみのために、.NET 3.5 も試してみましたが、いずれもリークは発生しませんでした。

于 2013-02-02T23:34:16.970 に答える