2010-02-12 3 views
1

아래 코드에서 'System.OutOfMemoryException'이 계속 발생합니다. 메모리 누수가 어디인지 알 수 없으며 누군가 내가 잘못하고있는 것을 설명 할 수 있다면 큰 도움이 될 것입니다. 감사!코드 검토 : OutOfMemoryException 문제

lock ((_tabs)) 
{ 
    System.IO.StreamReader sr = null; 
    System.IO.MemoryStream ms = null; 
    try 
    { 
     Type[] t = { typeof(tsgPublicDecs.tsgClsTab) }; 
     System.Xml.Serialization.XmlSerializer srl = new System.Xml.Serialization.XmlSerializer(typeof(ArrayList), t); 
     ms = new System.IO.MemoryStream(); 
     srl.Serialize(ms, _tabs); 
     ms.Seek(0, 0); 
     sr = new System.IO.StreamReader(ms); 
     return sr.ReadToEnd(); 
    } 
    finally 
    { 
     if (((sr != null))) 
     { 
      sr.Close(); 
      sr.Dispose(); 
     } 
     if (((ms != null))) 
     { 
      ms.Close(); 
      ms.Dispose(); 
     } 
    } 
} 

편집 :이 질문 몇 가지 답변하려면 :

  • _tabs 많은 다른 질문이 나타납니다 아무것도 (채워되지 않는 이유는도 사용하지만 난해야합니다 그것에 대해 작성한 개발자에게 물어보십시오.
  • 오류를 발생시키는 줄은 'srl.Serialize (ms, _tabs);'입니다.
  • 이 오류는 임의적이며 직접 복제 할 수 없지만 몇 일이 지나면 실행됩니다.이 오류는 발생합니다. 이 때문에 나는 던져진 오류를 넘어서는 정보를 얻을 수 없다.

편집 2 : 모든 입력 감사합니다. 사용 방법을 추가하고 다른 가능한 메모리 누수를 찾는 것이 가장 좋은 방법 인 것 같습니다. 얼마나 빨리 사람들이 손을 빌릴 수 있는지를 알면 좋습니다!

+0

"시도"를 사용하려는 경우 {} catch (예외) {} finally {}를 시도해야합니다. 즉, 캐치를 놓친 것입니다. –

+0

_tabs의 크기는 얼마나됩니까? –

+0

어떤 라인이 예외를 던지고 있습니까? – FrustratedWithFormsDesigner

답변

0

사용하는 블록이 두 개인데 비명을 지르고 있습니다.

lock ((_tabs)) 
{ 
     Type[] t = { typeof(tsgPublicDecs.tsgClsTab) }; 
     System.Xml.Serialization.XmlSerializer srl = new System.Xml.Serialization.XmlSerializer(typeof(ArrayList), t); 

     using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) 
     { 
      srl.Serialize(ms, _tabs); 
      ms.Seek(0, 0); 

      using (System.IO.StreamReader sr = new System.IO.StreamReader(ms)) 
      { 
      return sr.ReadToEnd(); 
      } 
     } 


} 

+2

이 코드는 작동하지 않으며 컴파일되지 않습니다. A) finally 블록을 'using'으로 사용할 필요가 없으며 B) 범위 밖에서 MemoryStream을 사용하고 있습니다. – ladenedge

+0

중첩 된 사용 블록이 필요합니다. – kervin

+0

또한,이 코드가 kervin이 언급 한대로 적절하게 형성되었다고해도, 순수한 구문 적 조정을 제공하기 때문에 메모리 부족 문제를 해결하지 못합니다. (블록을 사용하는 것이 멋진 일은 아니라는 것을 말하는 것은 아닙니다.) – ladenedge

0

_tabs의 크기에 따라 sr.ReadToEnd()을 통해 전체 직렬화 스트림을 읽는 것이 원인 일 수 있습니다.

+0

stewsha는 예외가 Serialize() 행으로 되돌아 가고 있다고 말했습니다. sr.ReadToEndAsync()를 호출하는 경우 sr.ReadToEnd()가 발생하는 유일한 방법 –

0
  1. 다른 사람이 말한 것처럼, 나는 _tabs을 의심한다.

  2. 발생하는 예외를 중단하고 크기를 확인하도록 Visual Studio를 설정하십시오.

  3. 단순히 폐기하려는 경우 finally 블록 대신 중첩 된 'using'블록을 사용하는 것이 좋습니다.

  4. 메모리 부족 예외가 발생하면 몇 개의 스레드가 실행되고 있습니까? 메모리가 이미 사용 된 경우 코드 블록이 중단 될 수 있습니다.

0

이 시도 .. 을이 SnippetCompiler에서 실행됩니다. 작동하지 않는다면 tsgClsTab 클래스에 순환 참조가 있습니다. 그리고, 그래, 조회 'using'을 ;-)

using System; 
using System.Collections; 
using System.IO; 
using System.Xml.Serialization; 

public class MyClass 
{ 
    public static void RunSnippet() 
    { 
     var _tabs = new ArrayList(); 

     _tabs.Add(new tsgClsTab(1)); 
     _tabs.Add(new tsgClsTab(2)); 
     _tabs.Add(new tsgClsTab(3)); 
     _tabs.Add(new tsgClsTab(4)); 

     lock ((_tabs)) 
     { 
      StreamReader sr = null; 
      MemoryStream ms = null; 
      try 
      { 
       var srl = new XmlSerializer(typeof (ArrayList), 
              new Type[] {typeof (tsgClsTab)}); 
       ms = new MemoryStream(); 
       srl.Serialize(ms, _tabs); 
       ms.Seek(0, 0); 
       sr = new StreamReader(ms); 
       Console.WriteLine(sr.ReadToEnd()); 
      } 
      finally 
      { 
       if (((sr != null))) 
       { 
        sr.Close(); 
        sr.Dispose(); 
       } 
       if (((ms != null))) 
       { 
        ms.Close(); 
        ms.Dispose(); 
       } 
      } 
     } 
    } 

    #region Helper methods 

    public static void Main() 
    { 
     try 
     { 
      RunSnippet(); 
     } 
     catch (Exception e) 
     { 
      string error = string.Format("---\nThe following error occurred while executing the snippet:\n{0}\n---", 
             e.ToString()); 
      Console.WriteLine(error); 
     } 
     finally 
     { 
      Console.Write("Press any key to continue..."); 
      Console.ReadKey(); 
     } 
    } 

    #endregion 

    #region Nested type: tsgClsTab 

    public class tsgClsTab 
    { 
     public tsgClsTab() 
     { 
     } 

     public tsgClsTab(int id) 
     { 
      Id = id; 
     } 

     public int Id { get; set; } 
    } 

    #endregion 
} 

OUTPUT

<?xml version="1.0"?> 
<ArrayOfAnyType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <anyType xsi:type="tsgClsTab"> 
    <Id>1</Id> 
    </anyType> 
    <anyType xsi:type="tsgClsTab"> 
    <Id>2</Id> 
    </anyType> 
    <anyType xsi:type="tsgClsTab"> 
    <Id>3</Id> 
    </anyType> 
    <anyType xsi:type="tsgClsTab"> 
    <Id>4</Id> 
    </anyType> 
</ArrayOfAnyType> 
3

당신은 문제가 여기에 있는지 확인 있습니까?

다른 곳에서 메모리가 누출되지 않습니까?

OutOfMemoryException은 어디에서나 메모리를 할당 할 때 발생할 수 있으며 여기에서 일어난 일은 우연 일 수도 있습니다.

메모리 프로파일 러에서 응용 프로그램의 프로필을 작성하여 메모리가 누출 될 수있는 참조가 있는지 확인하십시오.

가능한 한 많은 RAM을 테스트 컴퓨터에서 제거하십시오 (OS에 따라 XP에서 256/128MB로 내려가십시오). 반복적 인 사용 사례를 여러 번 실행하십시오 (사용 사례 하나가 반드시 실행되는 것은 아닙니다) 이 코드).

0

또 다른 제안은, 당신이 그것을 스윙 수 있다면. private ArrayList _tabs = new ArrayList(); 새로운 :

세 : private List<tsgPublicDecs.tsgClsTab> _tabs = new List<tsgPublicDecs.tsgClsTab>();

을 그리고 유사 XmlSerializer 인스턴스를 조절 같은 일반적인 강력한 형식의 로모그래퍼 _tabs '선언 (내가 somwhere ArrayList로 선언 가정한다) 교체합니다.

꽤 기본적인 테스트를 마친 후에 OOM 예외가 발생하지는 않습니다.

lock (_tabs) 
    { 
     Type[] t = { typeof(tsgPublicDecs.tsgClsTab) }; 
     System.Xml.Serialization.XmlSerializer srl = new System.Xml.Serialization.XmlSerializer(typeof(ArrayList), t); 
     using (System.IO.Stream ms = new System.IO.MemoryStream()) 
     { 
      srl.Serialize(ms, _tabs); 
      ms.Seek(0, 0); 
      using (System.IO.TextReader sr = new System.IO.StreamReader(ms)) 
      { 
       return sr.ReadToEnd(); 
      } 
     } 
    } 

편집 :가 아니라 무엇을 생각 여기에 다른 사람이 using이와 단순화로 말했다 무엇인가? OutOfMemoryException이 발생할 수있었습니다. 그러나 이들 중 10,000 개의 arraylist 만이 각각의 항목에 이전 참조를 가지고 있습니다. 따라서 오브젝트 그래프에 도달하면 매우 복잡한 오브젝트 그래프가 나타나며, 이는 사용자가 마주 치게 될 수도 있습니다.