2017-11-25 5 views
0

Memory Out of Range例外は、2つのjpegファイルを比較する静的メソッドです。静的メソッドのメモリ範囲外例外の取得

私はプロファイラを使用して、ほとんどのメモリを消費している私のコードのどの部分を識別することができています、しかし、私も、私は(GC.Collectを試してみました、メモリを解放することはできませんよ)

public static bool IsDuplicate(string newFile, string pathDestination) 
{ 
    string[] destinationFiles = Directory.GetFiles(pathDestination); // 1100 jpeg files. 
    foreach (var file in destinationFiles) 
    { 
     if (CompareImageFiles(newFile, file)) 
      return true; 
    } 
    return false; 
} 

//1100 jpeg files (pathFile2) being compared with one jpeg file (pathFile1) 
public static bool CompareImageFiles(string pathFile1, string pathFile2) 
{ 
    // Memory consumption around 1 GB by ms 
    MemoryStream ms = new MemoryStream(); 
    // Memory consumption around 2.7 GB by img1 
    System.Drawing.Image img1 = System.Drawing.Image.FromFile(pathFile1); 

    // Memory consumption around 3 GB by img2 
    System.Drawing.Image img2 = System.Drawing.Image.FromFile(pathFile2); 
    if (!(img1.Height == img2.Height && img1.Width == img2.Width)) 
    { 
     return false; // Dimensions mismatch 
    } 
    else 
    { 
     img1.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); 
     string image1 = Convert.ToBase64String(ms.ToArray()); 
     img2.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); 
     string image2 = Convert.ToBase64String(ms.ToArray()); 
     if (image1.Equals(image2)) 
     { 
      // This didn't work 
      //ms = null; img1 = null; img2 = null; image1 = null; image2 = null; 
      return true; 
     } 
     else 
     { 
      // This didn't work 
      //ms = null; img1 = null; img2 = null; image1 = null; image2 = null; 
      return false; 
     } 
    } 
} 

リトル背景:はい、これは画像ファイルを比較するための完全な方法ではありません(私の最初の画像ファイル対応の試み)。私はすでにこのタスクの新しい最適化バージョンを開始しました(進行中)。

しかし、この解決策は過去数ヶ月から働いていて、最近崩壊し始めています。ですから、私はこのアプローチを少なくともアーカイブする前に、私に良い学習をもたらした問題を解決したいと思っていました。

+5

どのように最初のファイル - の比較について処理を中止するサイズ?次に、ファイルをハッシュし、ハッシュを比較します。違いがある場合、内部的にも異なります。このイメージのものは必要ありませんか?あなたがしていることよりはるかに高速で、より多くのリソースにやさしいことが必要です。 –

+1

あなたのアプリが漏れています。 'Dispose'メソッドを実装するものは、処理が終わった時点で処理する必要があります。 – Plutonix

+0

これを試してみてください:https://stackoverflow.com/a/16318177/7505395 –

答えて

4
あなたは、どちらかの using声明の中で、それらを配置することによって、または、あなたが彼らと終わったら手動 Dispose()を呼び出すことによって、あなたの Imageインスタンスとメモリストリームを処分する必要があり

public static bool CompareImageFiles(string pathFile1, string pathFile2) 
{ 
    using (var ms = new MemoryStream()) 
    using (var img1 = System.Drawing.Image.FromFile(pathFile1)) 
    using (var img2 = System.Drawing.Image.FromFile(pathFile2)) 
    { 
     // Rest of your code... 
    } 
} 
+2

追加するには、例外が発生した場合の適切な処分も扱うため、一般的には「使用する」を使用するのが好ましい方法です。 Disposeは、 "using"を使用できない場合、またはDisposeメソッド/ファイナライザで直接呼び出される必要があります。 – ckuri

関連する問題