2016-06-27 104 views
-5

我有一個內存不足的程序。我不明白爲什麼當我設置object = null時,它已被「處理​​」。C#程序內存不足

foreach (DataRow theRow in thisDataSet.Tables["Collection"].Rows) 
{ 
    LS_BatchAID = Convert.ToString(theRow["BatchAID"]); 
    LS_Batch = Convert.ToString(theRow["Batch"]); 
    LS_ID = Convert.ToString(theRow["ID"]); 
    CL_Batch Batch = new CL_Batch(LS_BatchAID, LS_ID, LS_Batch); 
    Batch = null; 
} 

thisConnection.Close(); 

我得到這個錯誤:System.OutOfMemoryException的」出現在mscorlib.dll 當運行程序,看任務管理器,我可以在對應線看內存消耗上升的代碼的迭代次數。

我該如何製作一個不增加內存消耗/轉儲的程序?

CL_Batch: 

class CL_Batch 
    { 
     private string BatchAID; 
     private string ID; 
     private string Batch; 
     private string pathPDF; 
     private string pathCPR; 
     private string pathLog; 
     private string DateXMLGenerated; 

     private string[] IDType; 
     private string[,] IDTypes; 
     private string[] Files; 
     private DateTime Dates; 
     private byte[] pdfContent; 
     private string XMLContent; 
     private string[] RefNbr; 

     public CL_Batch(string IV_BatchAID, string IV_ID, string IV_Batch) 
     { 
      this.Dates = DateTime.Now; 

      this.DatoXMLGenerated = "" + Dato.Date.Year.ToString() + "-" + BuildNumber(true, 2, Dato.Date.Month.ToString()) + "-" + BuildNumber(true, 2, Dato.Date.Day.ToString()) + ""; 
      this.BatchAID = IV_BatchAID; 
      this.ID = IV_ID; 
      this.Batch = IV_Batch; 
      this.pathPDF = @"C:\path\TempFiles\path\" + this.ID + ".Pdf"; 
      this.pathCPR = @"C:\path\TempFiles\"; 
      this.pathLog = @"C:\path\Log\" + this.Batch + ".txt"; 

      setRefnbr(); 

       // Set array with mappings of ID between partners. 
       setLegitimationsTyper(); 

       // ensure log is available ([NameOfLog]). 
       prepareLog(); 

       // Find all files for archive. 
       getFileNames(); 

       // Move files C:\path\TempFiles\ 
       if (this.getFiles() == true) 
       { 
        // Create PDF's. 
        makePDF(); 

        // Insert PDF's in database. 
        insertPDF(); 

        // Create XML files. 
        makeXML(); 

        // Insertt XML in database. 
        insertXML(); 

       } 



     public string getBatchAID() 
     { 
      return this.BatchAID; 
     } 

     public string getID() 
     { 
      return this.ID; 
     } 

     public string getBatch() 
     { 
      return this.Batch; 
     } 

     public string getIDTyper(string IV_Code, bool kode) 
     { 

      for (int i = 0; i <= this.IDTypes.GetUpperBound(0); i++) 
      { 
       if (this.IDTypes[i, 0] == IV_Kode) 
       { 
        if (Code == true) 
        { 
         return this.LegitimationsTyper[i, 1]; 
        } 
        else 
        { 
         return this.LegitimationsTyper[i, 2]; 
        } 
       } 
      } 
      return ""; 
     } 
} 

/**************************************/

/**更新#1 **********/

很公平!濫用構造函數。我明白了 - 但是: 真的是什麼問題?

如果我這樣做,因爲我已經做了與這個例子:

CL_Batch Batch = new CL_Batch(LS_BatchAID, LS_ID, LS_Batch); 

Batch.setRefnbr(); 
Batch.setIDTypes(); 
Batch.prepareLog(); 
Batch.getFileNames(); 
Batch.makePDF(); 
Batch.insertPDF(); 
Batch.makeXML(); 
Batch.insertXML(); 
Batch = null; 

那麼,什麼是真正的差異? 如果是以不同的方式添加幾個數字,那麼它會以相同的指令結束。

First program: 
xor ax, ax 
mov ax, 10 
add ax, 10 

Second program: 
xor ax, ax 
mov ax, 10 
add ax, 10 

我看到它有最終沒有差異的方式(我偵察,我濫用了面向對象的概念,但最終產物是相同的 - 我希望)

請諮詢我關於我的錯覺。

在此先感謝。 /**更新#1/ /**************************************** **/

+8

什麼是CL_Batch? – BugFinder

+2

將你的片段縮小到「foreach」並不是減少噪音的方法 - 如果你只是減少整個班級的噪音並向我們展示這個減少的班級會更好 - 你永遠不知道它可能是什麼不在你的foreach循環中 –

+1

我認爲你的問題可能圍繞你內存中的字符串數量,但是你需要對此進行配置以找到實際答案,使用dotMemory或類似的方法 –

回答

0

儘管我不同意關於錯誤構造函數代碼的提議,但是我必須承認它有所作爲,代碼在從構造函數中刪除代碼後按預期工作。 如果有人對我有一個很好的解釋,那麼我想聽聽它。 反正是有,我可以給你們(BugFinder, 卡勒姆Linington, Mixxiphoid, ManoDestra, 麥克·羅賓遜, 馬修粉飾, 斯科特Hannen)信貸的解決方案嗎?

這是工作的代碼:

foreach (DataRow theRow in thisDataSet.Tables["Collection"].Rows) 
{ 
    LS_BatchAID = Convert.ToString(theRow["BatchAID"]); 
    LS_Batch = Convert.ToString(theRow["Batch"]); 
    LS_ID = Convert.ToString(theRow["ID"]); 
    CL_Batch Batch = new CL_Batch(LS_BatchAID, LS_ID, LS_Batch); 
    Batch.setRefnbr(); 
    Batch.setIDTypes(); 
    Batch.prepareLog(); 
    Batch.getFileNames(); 
    Batch.makePDF(); 
    Batch.insertPDF(); 
    Batch.makeXML(); 
    Batch.insertXML(); 
} 
thisConnection.Close(); 
+1

這不是一個答案。你應該刪除這個。而且,您仍然在數據循環中執行所有處理。最後你不需要Batch = null行。它只在每次迭代中被實例化,無論如何它都會被重新實例化,所以毫無意義地將它設置爲null。問題在於後續的方法。我不會做你在這裏做的事情。我會在這個之外的一個單獨的循環中執行這個處理,但至少現在你可以更好地識別發生內存泄漏的地方,因爲你已經打破了邏輯。 – ManoDestra

+0

@ManoDestra感謝您的回覆。關於該程序,內存消耗如預期那樣上下移動 - 現在。 關於您在數據循環內處理的聲明。 如果不是這樣,我該怎麼做?提前致謝。 請溫和我。我在這裏被打敗了。 –

+1

這樣做的兩種方法。您在這裏完成的方式更好,因爲您應該更好地理解內存消耗使程序崩潰的線路。從那裏,你可以深入瞭解原因。就個人而言,我會將所有這些方法調用(.setRefnbr(),setIDTypes()等)移至第二個循環。因此,如上所述遍歷表中的行,但將每個CL_Batch添加到List中。然後在此循環之後循環訪問該列表,然後執行方法調用。合理? – ManoDestra

3

這是在黑暗中刺,因爲我們看不到您的代碼。您正在創建PDF。這通常涉及某種COM對象或內存流。也許無論你用什麼來創建這些PDF文件都不會被處理或清理,所以你創建的每個PDF文件都在內存中,直到用完爲止。我會仔細看看你正在使用的任何組件的文檔。如果有東西實現IDisposable請確保你正在處置它。