2012-08-30 59 views
2

我試圖運行這個方法,它工作正常,但幾百內部迭代的我因內存不足異常後獲得每次:減少文件操作的內存佔用

... 
MNDBEntities db = new MNDBEntities(); 
var regs = new List<DOCUMENTS>(); 
var query = from reg in db.DOCUMENTS 
      where reg.TAG_KEYS.Any(p => p.TAG_DATE_VALUES.FirstOrDefault().TAG_DATE_VALUE.HasValue 
       && p.TAG_DATE_VALUES.FirstOrDefault().TAG_DATE_VALUE.Value.Year == 2012) 
      select reg; 

var pages = new List<string>(); 
foreach (var item in query) 
{ 
    Document cert = new Document(); 

    var tags = item.TAG_KEYS; 
    foreach (var tag in tags) 
    { 
     // Basic stuff... 
    } 

    var pagesS = item.PAGES; 
    foreach (var page in pagesS) 
    { 
     var path = @"C:\Kumquat\" + (int)page.NUMBER + ".vpimg"; 
     File.WriteAllBytes(path, page.IMAGE); 
     pages.Add(path); 
     Console.WriteLine(path); 
    } 

    //cms.Save(cert, pages.ToArray()).Wait(); 
    foreach (var pageFile in pages) 
     File.Delete(pageFile); 

    pagesS = null; 
    pages.Clear(); 
} 
... 

我敢肯定的問題與File.WriteAllBytes或File.Delete有關,因爲如果我註釋這些行,該方法無例外地運行。我所做的基本上是從數據庫和文檔圖像中獲取一些標籤,然後將該圖像保存到磁盤上,然後將其存儲到cms中,然後從磁盤中刪除。老實說,不知道我在做什麼錯誤的文件調用。任何想法?

這是PerfView顯示:

​​

這是什麼的Visual Studio 2012探查器顯示爲熱點,事情是:這是所有生成的代碼(實體模型內)我在幹嘛模型的屬性可能有問題嗎?

enter image description here

+0

你的'db'應該在'使用',是嗎?在這裏玩什麼其他'IDisposable'類?也許'文件'? – Blorgbeard

+0

您的查詢返回的記錄大概有多少,以及每個記錄的「IMAGE」有多大? – vane

+0

如果你在'WriteAllBytes'中發現了泄漏,'File.Delete'幾乎不能分配內存(可以這麼說),我會感到驚訝。你需要看看你是如何實例化你的數據,並可能實現某種處置模式,以確保你不會耗盡內存。但是,如果不知道'cms'是什麼,或者確切知道你從數據庫中提取什麼樣的數據,就很難推薦特定的東西。 – kprobst

回答

2

嘗試使用http://www.microsoft.com/en-us/download/details.aspx?id=28567來分析代碼,專注於GC事件和CLR管理分配滴答事件。

page.IMAGE可能是問題。它很可能會分配一個字節數組並永遠不會刪除它。最好將代碼更改爲:

page.WriteTo(path); 

顯示的其餘代碼看起來不錯。唯一可能的問題是大對象分配,這可能導致LOH中的碎片問題。

+0

Feng Page.IMAGE是一個byte [],沒有page.WriteTo,這就是File.WriteAllBytes(路徑,頁面)。圖片);是在做。我會嘗試使用您的建議工具併發布。 –

+0

經過艱苦的工作,你是對的。這是一個與創建大字節數組的實例(在LOH中)有關的問題。我更改了代碼屬性,刪除了嵌套的實體框架代碼,並將其替換爲自定義的本機SQL。抱歉,最初的倒退,在開始時不明白你的迴應。 +1並被接受。非常感謝你。 –