2017-10-30 5 views
1

나는 하나의 파일에 많은 수의 작은 XML 파일을 꿰맬 수 있으며 각 파일에 해당하는 1 바이트 배열로 행을 반환하는 사용자 지정 추출기를 만들었습니다. (gzip으로 압축, 11MB) 하나 개의 파일에 대한 원격에OutOfMemory on custom extractor

  1. 실행/마스터
    • 실행은, 그것을 잘 작동합니다.
    • 하나 이상의 파일을 실행하면 System.OutOfMemoryException이 발생합니다. 지역/마스터 (500 MBS를 gzip으로 압축) 하나 개 이상의 파일에 대한
      • 실행 그것을
    • 실행은 잘 작동합니다.

추출기는 다음과 같습니다

그래서
==== Caught exception System.OutOfMemoryException 

at System.Xml.XmlDocument.CreateTextNode(String text) 
at System.Xml.XmlLoader.LoadAttributeNode() 
at System.Xml.XmlLoader.LoadNode(Boolean skipOverWhitespace) 
at System.Xml.XmlLoader.LoadDocSequence(XmlDocument parentDoc) 
at System.Xml.XmlDocument.Load(XmlReader reader) 
at System.Xml.XmlDocument.LoadXml(String xml) 
at Microsoft.Analytics.Tools.Formats.Text.XmlByteArrayRowExtractor.<Extract>d__0.MoveNext() 
at ScopeEngine.SqlIpExtractor<ScopeEngine::GZipInput,Extract_0_Data0>.GetNextRow(SqlIpExtractor<ScopeEngine::GZipInput\,Extract_0_Data0>* , Extract_0_Data0* output) in d:\data\ccs\jobs\bc367467-ef86-43d2-a937-46ba2d4cc524_v0\sqlmanaged.h:line 1924 

내가 뭘 잘못하고있다 :

public override IEnumerable<IRow> Extract(IUnstructuredReader input, IUpdatableRow output) 
    { 

     using (var stream = new StreamReader(input.BaseStream)) 
     { 
      var xml = stream.ReadToEnd(); 

      // Clean stiched XML 
      xml = UtilsXml.CleanXml(xml); 

      // Get nodes - one for each stiched file 
      var d = new XmlDocument(); 
      d.LoadXml(xml); 
      var root = d.FirstChild; 

      for (int i = 0; i < root.ChildNodes.Count; i++) 
      { 
       output.Set<object>(1, Encoding.ASCII.GetBytes(root.ChildNodes[i].OuterXml.ToString())); 
       yield return output.AsReadOnly(); 
      } 

      yield break; 
     } 
    } 

및 오류 메시지가 다음과 같습니다? 원격으로 이것을 디버깅하려면 어떻게해야합니까?

감사합니다.

답변

1

로컬 런은 메모리 할당을 시행하지 않으므로 로컬 버텍스에서 메모리를 직접 검사해야합니다.

위의 코드를 살펴보면 XML 문서를 DOM에로드하고있는 것을 알 수 있습니다. XML DOM은 문자열 표현에서 최대 10 배까지 데이터 크기를 폭발시킬 수 있다는 점에 유의하십시오 (필자는 상주 SQL XML 전문가로서 내 시간에 2 ~ 12 회를 보았습니다).

각 UDO는 현재 1/2GB의 RAM 만 가지고 있습니다. 그래서 내가 가정하는 것은 XML DOM 문서가 그 이상으로 시작된다는 것입니다.

일반적으로 XMLReader 인터페이스 (http://usql.io의 샘플에도 판독기 추출기가 있음)를 사용하고 문서를 검색하여 원하는 정보를 찾는 것이 좋습니다.

문서가 항상 작은 경우 (예 : < 20MB) 다른 문서의 메모리를 해제하고 한 번에 하나의 문서 만 조작해야 할 수 있습니다.

UDO에 메모리 요구에 주석을 달 수 있도록 계획을 세웠지 만, 여전히 조금 부족합니다.

+0

당신은 메모리 예외의 원인에 대해 옳았습니다. 내 사용자 지정 추출기를 다시 코딩하여 XmlReader로 대신 작업 한 다음 문서를 DOM에로드하지 않아도 아무런 문제가 없습니다. xml은 아주 훌륭하고 깨끗한 XML 파일이 아니고 아주 깊은 xml 구조이기 때문에 자체 추출기를 사용해야합니다. 그래서이 예제의 기존 추출기를 사용하지 않습니다. 도움을 많이 주셔서 감사합니다! – Anders