2016-06-27 3 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 ""; 
     } 
} 

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

/** UPDATE # 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 

나는 그것이 결국에는 차이가 없다 볼 수있는 방법은 (내가 OOP의 개념을 오용하는 것을 정찰하지만, 최종 생성물 인은 동일합니다 - 내가 예상)

나에게 조언을 내 망상에 관한하세요 .

미리 감사드립니다. /** 업데이트 # 1/ /**************************************** **/

+8

입니다 :

이 작동 코드는? – BugFinder

+2

스 니펫을 'foreach'로 축소하는 것은 우리에게 발생하는 노이즈를 최소화하는 방법이 아닙니다. 전체 클래스의 노이즈를 줄이고이 감소 된 클래스를 보여 주면 좋을 것입니다. 귀하의 foreach 루프에 없습니다 –

+1

귀하의 문제는 귀하의 메모리에있는 문자열의 양을 주위에있을 수 있다고 생각하지만, 실제 대답을 찾을 수 dotMemory 또는 이와 유사한를 사용해야합니다 –

답변

0

잘못된 생성자 코드와 관련된 제안에 동의하지는 않지만 생성자에서 코드를 제거한 후에 코드가 의도 한대로 작동한다는 점을 인정해야합니다. 누구든지 나를 잘 설명하면 듣고 싶습니다. 어쨌든 거기에 내가 너희들 (BugFinder, 캘럼 Linington, Mixxiphoid, ManoDestra, 마이크 로빈슨, 마태 복음 회칠 한, 스콧 Hannen) 솔루션에 대한 신용을 줄 수 있습니까? CL_Batch 무엇

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() 등)을 두 번째 루프로 이동합니다. 위와 같이 테이블의 행을 반복하면서 List에 각 CL_Batch를 추가하십시오. 그런 다음이 루프 이후에 해당 목록을 반복하고 대신 메서드를 호출합니다. 이해가 되니? – ManoDestra

3

코드를 볼 수 없어 어둠 속에서 찌르는 것입니다. PDF를 작성 중입니다. 그것은 종종 COM 객체 나 메모리 스트림을 포함합니다. 어쩌면 당신이 그 PDF를 만드는 데 사용하고있는 것은 폐기되거나 정리되지 않기 때문에, 당신이 만든 모든 PDF는 당신이 다 떨어질 때까지 메모리에 저장됩니다. 사용중인 구성 요소에 대한 설명서를 자세히 살펴 보겠습니다. 무언가가 IDisposable을 구현하면 폐기 처분해야합니다.

관련 문제