2014-11-06 91 views
0

我發誓我知道這個答案,但我忘了。加載大量的圖像導致內存不足

我有這個功能。它加載位圖並繪製它們。它可以快速連續調用。大約300左右的位圖後,應用程序崩潰,出現System.OutOfMemoryException。

請告訴我,我錯了又來了:)

private void PaintPicture() 
    { 
     string FullPath = Global.RunttimePath + EditType.FilePath; 

     if (File.Exists(FullPath)) 
     { 
      Image i = Image.FromFile(FullPath); 
      //DrawImage(i, pnlPicture, pbColor.BackColor); //I disabled this so the problem is not here 
      i.Dispose(); 
      //GC.Collect(); //I know I know... I should never call GC. So disabled it :) 
     } 
     else 
     { 
      //DrawImage(Properties.Resources.Fail800, pnlPicture, Color.White, true); 
     } 
    } 
+1

在你的示例代碼中,你沒有做錯任何事情,要麼你的問題的來源是其他地方,這段代碼只是「St原料打破了駱駝回來「或問題是在你刪除的代碼發佈你的問題在這裏。 – 2014-11-06 18:26:18

+0

圖像是GDI資源,無論如何都不需要GC'd。 – TaW 2014-11-06 18:38:57

回答

3

Image.FromFile的文檔,你可以得到一個OutOfMemoryException如果位圖處於未知格式。確保您的應用程序可以安全地加載您嘗試使用的所有圖像,並查看它是否總是在同一圖像上崩潰。

如果它總是相同的圖像,那麼你可以嘗試重新保存支持的像素格式的圖像(使用Photoshop或Paint.Net或其他免費工具) - 這應該修復破壞應用程序的特定圖像。

此外,添加一個異常處理程序在你的繪圖邏輯,以確保當它運行到一個不好的形象您的應用程序不會崩潰 - GDI +僅支持的圖像格式數量相對較少。

要驗證是否你實際上運行內存(也就是說,如果有泄漏),您的應用程序運行時監視內存的使用。如果你看到內存泄漏的跡象,你的問題可能在其他地方。

編輯:

閱讀這些問題/解答諮詢有關使用Image.FromStream代替FromFile() - 這樣做可以避免鎖定很長一段時間的文件:

File.Delete failing when Image.FromFile was called prior it, despite making copy of loaded image and destroying original one

out of memory Image.FromFile

+0

噢呃...我知道..我應該檢查這個。某種程度上4623圖像中的12個被損壞了。由於線程加載器,我正在執行它,其中任何一個都會崩潰。感謝大家的幫助:) – user2888973 2014-11-06 19:03:59

+0

@ user2888973我知道那是怎麼回事,過去我遇到過類似的問題。在一個巨大的文件夾中很難看到壞圖片。 – xxbbcc 2014-11-06 19:06:19

+0

@ user2888973我添加了一個鏈接,解釋了爲什麼'FromStream()'比'FromFile()'好。 – xxbbcc 2014-11-06 19:09:23

1

這可能不會解決你的問題,但圖像類實現了IDisposable。這意味着你可以將它包裝在一個USING語句中,這會使得對象內部的對象超出範圍更快/更少的對象繼續存在於L2垃圾收集中(它不應該在使用和調用處理中包裝事物之間做出區別,但我們通過內存分析發現它實際上是這樣)。

if (File.Exists(FullPath)) 
    { 
     using(Image i = Image.FromFile(FullPath)) 
     { 
      DrawImage(i, pnlPicture, pbColor.BackColor); //I disabled this so the problem is not here 
      //GC.Collect(); //I know I know... I should never call GC. So disabled it :) 
     } 
    } 
    else 
    { 
     //DrawImage(Properties.Resources.Fail800, pnlPicture, Color.White, true); 
    } 
} 
+0

+1簡化我的代碼 – user2888973 2014-11-06 19:06:21

相關問題