2010-01-25 3 views
2

.net에서 멀티 스레딩 문제가 있습니다. 다음 코드를 사용하십시오.ActiveX 개체 및 .NET 가비지 수집기

class Program 
{ 
    private static ManualResetEvent[] resetEvents; 

    private void cs(object o) 
    { 
     int xx = 0; 
     while (true) 
     { 
      xx++; 
      System.Xml.XmlDocument document = new System.Xml.XmlDocument(); 
      document.Load("ConsoleApplication6.exe.config"); 

      MSScriptControl.ScriptControlClass s = 
       newMSScriptControl.ScriptControlClass(); 
      s.Language = "JScript"; 
      object res = s.Eval("1+2"); 
      Console.WriteLine("thread {0} execution {1}" , o , xx); 
      System.Threading.Thread.Sleep(5000); 
     } 

    } 
    static void Main(string[] args) 
    { 
     Program c = new Program(); 
     for (int i = 0; i < 1000; i++) 
     { 
      System.Threading.Thread t = new System.Threading.Thread(
       new System.Threading.ParameterizedThreadStart(c.cs)); 
      t.Start((object)i); 
     } 
    } 
} 

이 코드가 실행되면 몇 분 후에 충돌합니다. 왜 충돌하는거야? 충돌을 막기 위해 무엇을 할 수 있습니까?

+2

예외는 무엇입니까? –

답변

2

1000 개의 스레드가 시작됩니다. 그것은 스택 공간과 스레드가 생성하는 모든 객체에 1000MB가 있습니다. 내 추측으로는 네가 기억이 부족하다. 무엇을 성취하려고합니까?

+0

@ 브라이언 : 와우. 그는 실제로 쉽게 StackOverFlow 쉬운 방법을 만들었습니다 :) –

+0

@ 조엘 : 코드가 스택을 소모하지 않기 때문에 OP가 StackOverflowException을 받고 있는지 의심 스럽다. OutOfMemoryException이 될 수 있습니다. –

+0

스택 공간에서 1000MB를 어떻게 파악합니까? 4 ('o') +4 ('xx') +4 ('문서') +4 ('s') +4 ('res') +4 (반송 주소) * 1000 바이트 = 6KB . –

0

응용 프로그램 코어 컨텍스트 스위칭을 많이 쓰는 프로세서 코어보다 많은 스레드를 생성하는 것은 거의 불가능하며 성능이 향상되는 경우 많이 볼 수 없습니다. 같은 시간에 실행되는 유일한 스레드 수는 시스템에있는 코어 수와 같습니다. 왜 1000 개의 스레드로이 작업을 수행해야합니까? (당연히 나는 1000 코어 머신이 없다고 가정한다)

0

제공된 코드가 주어지면 분명히 보이지 않을 수도있는이 어플리케이션의 몇 가지 측면이있을 수있다. 즉, 나는 크래시를 재현 할 수 없었지만 외설적 인 메모리 사용량 (29 "xx ++"에서 160MB)을 실행할 수있었습니다.

나는 ScriptControlClass가 메모리에 살아 있다고 추측합니다.

Console.WriteLine("thread {0} execution {1}" , o , xx); 
s = null; 

UPDATE
이 코드와 비슷한 결과를 가지고이 문제를 해결하는 더 나은 방법이있을 수 있지만,이 또한으로 일관 60-70메가바이트에서 메모리를 유지 할 수 있었다 메모리 - 현명하지만 아래의 코드는 약간 빠릅니다. 몇 분 후 xx < 30true으로 다시 바뀌었을 때 메모리 사용량은 일관된 51MB였습니다.

class Program 
{ 
    private static ManualResetEvent[] resetEvents; 

    [ThreadStatic] 
    static ScriptControlClass s; 

    private void cs(object o) 
    { 
     int xx = 0; 

     if (s == null) 
     { 
      s = new ScriptControlClass(); 
     } 

     /* you should be able to see consistent memory usage after 30 iterations */ 
     while (xx < 30) 
     { 
      xx++; 

      //Unsure why this is here but doesn't seem to affect the memory usage 
      // like the ScriptControlClass object. 
      System.Xml.XmlDocument document = new System.Xml.XmlDocument(); 
      document.Load("ConsoleApplication6.exe.config"); 

      s.Language = "JScript"; 
      object res = s.Eval("1+2"); 
      Console.WriteLine("thread {0} execution {1}", o, xx); 

      System.Threading.Thread.Sleep(5000); 
     } 

     s = null; 

    } 
    static void Main(string[] args) 
    { 
     Program c = new Program(); 
     for (int i = 0; i < 1000; i++) 
     { 
      System.Threading.Thread t = new System.Threading.Thread(
       new System.Threading.ParameterizedThreadStart(c.cs)); 
      t.Start((object)i); 
     } 
    } 
} 

업데이트 2
내 인터넷 검색은 멀티 스레드 환경에서 ScriptControlClass 사용에 대한 아무것도 찾을 수 없습니다.

관련 문제