2012-09-25 2 views
0

데이터 집합을 생성하고 XML 데이터를 생성하는 함수가 있습니다. 이 기능은 완벽하게 작동합니다. 문제는 보고서를 여러 번 실행 한 후 "메모리 부족"오류가 발생한다는 것입니다. 보고서를 테스트 할 때이 XmlDocument 명령에 도달하면 메모리 사용량이 많이 증가한다는 것을 발견했습니다. GC를 사용했지만 사용하지 않았습니까?XmlDocument를 사용할 때 메모리가 부족합니다.

if (ddlDir.SelectedItem != null && ddlSec.SelectedItem != null) 
{ 
    using (DataSet dsClosedKPICalls = GetReportData()) 
    { 
     dsClosedKPICalls.DataSetName = "ClosedKPICalls"; 
     foreach (DataTable table in dsClosedKPICalls.Tables) 
     { 
      table.TableName = "ServiceInfo"; 
     } 
     XmlContent = dsClosedKPICalls.GetXml(); 
    } 

    XmlDocument XML_Data = new XmlDocument();   // contains the resultant XML data 

    XML_Data.LoadXml(XmlContent); 
    XmlNodeList TablesList = XML_Data.SelectNodes("ClosedKPICalls/ServiceInfo"); 

    for (int i = 0; i < TablesList.Count; i++) 
    { 
     XmlDocument innerXML = new XmlDocument(); 

     using (DataSet dsTaskDetails = getSplitupRecords(TablesList.Item(i).SelectSingleNode("ServiceNo").InnerText)) 
     { 
      dsTaskDetails.DataSetName = "TaskDetails"; 
      foreach (DataTable tbl in dsTaskDetails.Tables) 
      { 
       tbl.TableName = "RequestInfo"; 
      } 

      innerXML.LoadXml(dsTaskDetails.GetXml()); 

      TablesList.Item(i).AppendChild(XML_Data.ImportNode(innerXML.SelectSingleNode("TaskDetails"), true)); 

      innerXML = null; 
      GC.Collect(); 
      GC.WaitForPendingFinalizers(); 
     } 
    } 
} 
+0

논리를 나눌 수있는 방법에 대해 생각해보십시오. 한 테이블에있는 모든 테이블을 처리해야합니까? 메모리 풋 프린트를 줄이기 위해 XmlTextWriter를 사용할 수 있습니까? –

+0

답장을 보내 주셔서 감사합니다. 좀 더 설명해 주시겠습니까? – Noora

답변

1

XML 문서의 크기는 어느 정도입니까? 특히 약 85K보다 큰가?

.Net 프레임 워크는 ~ 85K보다 큰 할당에 사용되는 Large Object Heap (LOH)이라는 것을 사용합니다. XML 문서가 이보다 더 큰 경우 (문자열과 유사)은 LOH에 할당 될 것입니다. LOH의 문제는 압축되지 않았기 때문에 메모리 조각화가 발생하기 쉽기 때문에 프로세스가 일반적으로 메모리를 할당 할 수있을 때에도 OutOfMemoryExceptions이 던져 질 수 있습니다. 이 일 수 있습니다. 솔루션

당신은 85K 아래에 개체의 크기를 유지하기 위해 노력하여 LOH의 사용을 감소

  • 을 시도 할 수 있습니다. 이것은 응용 프로그램에 따라 달성하기 어려울 수 있지만 대용량 XML 문서를 여러 개의 작은 문서로 나눌 수 있습니다.
  • .Net 프레임 워크 v4.5를 타겟팅하고 이것이 도움이되는지 확인해보십시오. .NET 프레임 워크 v4.5에는이 경우 도움이 될 improvements to the LOH이 포함되어 있습니다. 이 인위적 일반적으로 낮은 세대 이상 세대에 객체와 "가비지 컬렉터와 혼란"을 홍보 할 수로 옆으로, GC.CollectGC.WaitForPendingFinalizers에 통화로

는 나쁜 생각입니다. 이러한 호출은이 경우 거의 확실하게 도움이되지 않습니다. 일반적으로 정확히을 알고있는 경우 가비지 수집을 수동으로 호출하는 것이 좋습니다.

+0

답장을 보내 주셔서 감사합니다. – Noora

+0

답장과 설명에 감사드립니다. xmlDocument를 사용하지 않고 xml 콘텐츠를 읽을 수있는 다른 방법이 있습니까? – Noora

+1

@Noora 예, [XmlReader] (http://msdn.microsoft.com/en-us/library/system.xml.xmlreader.aspx)는 전달 전용 XML 판독기이므로 XML 노드를 읽을 수 있습니다 전체 문서를 메모리에 보관하지 않고 노드별로, 단점은 사용하기가 훨씬 어렵다는 것입니다. 당신은'XmlDocument'를 문자열 대신에이 리더에서로드하려고 시도 할 수 있습니다. 아마도 XmlDocument 내부 객체가 아닌 LOH에있는 문자열 일 것입니다. – Justin

관련 문제