2017-11-25 231 views
0

我得到Memory Out of Range例外,用於比較兩個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方法/終結器時才應直接調用Dispose。 – ckuri