2016-06-27 77 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请确保你正在处置它。