2014-11-25 34 views
0

「N」線程同時工作TPL我觀察到的一個問題內存中變瘋了。我想明白爲什麼我們有這樣的行爲。爲什麼如果通過第三方物流創造了的EventWaitHandle

這是一個簡單的示例代碼。假設我們有一個生產者在產生數據時發出信號。在這個方法中,我們創建了'N'個消費者。

public void StartMultiConsumers() 
{ 
    //// main processor thread.. 

    while (true) 
    { 
     Task.Factory.StartNew(() => 
     { 
      wh.WaitOne(); // causes the memory to grow crazy high 
      wh.Reset(); 
     }); 
    } 
} 

我知道我們可以改進代碼,以便我們不創建無限數量的線程。但是由於TPL只能創建少量的線程。爲什麼我們有這樣的行爲。

w.WaitOne()導致內存增長的瘋狂高。但爲什麼?

回答

3

即得到由應用程序創建的每個線程,消耗資源的操作系統。你有一個緊密循環簡單地旋轉關閉新任務儘可能快的,並且僅僅依賴於線程池的限制。但是,這不會持續很長時間,因爲線程被紡起來受阻,很快線程池注入新的線程入池..

原因內存穗 - 在.NET中創建的每個線程,被分配一個1MB的默認堆棧。也有與線程相關的其他系統資源,但即使有單獨1MB,如果分拆1000個線程,你最終消耗1GB內存應用程序,這是做什麼都不,但在等待句柄等待


編輯:爲了使它顯得更加清晰,考慮以下 -

  • 線程1 - 最顯着的系統資源,堆棧的1MB分配。舉行 ,直到線程爲alive(包括阻塞)。
  • 線程2 - 最顯着的系統資源,堆棧的1MB分配。直到線程爲 存活(包括阻塞)。
  • ...
  • ...
  • 螺紋1000 - 最顯着的系統資源,堆棧的1MB分配。持續到線程爲alive (包括阻塞)。由1000 活着保持

總內存/阻塞線程 - 在一個最小(只考慮堆棧分配) - 1000MB。即1GB

+0

但是當我檢查到任務管理器我很難得到像14線程的數量因此,這意味着,有沒有那麼多的線程或任務管理器不顯示線程是否正確? – 2014-11-25 05:32:10

+0

也不是導致內存高的WaitOne()方法導致內存的線程數。所以如果我評論這條線,尺寸沒有太大的變化。 – 2014-11-25 05:33:55

+2

@DJ等待一個不會導致大內存使用率,這是你在線程中做的阻塞調用。你可以用'Thread.Sleep(10000)'代替WaitOne並看到相同的效果。 – 2014-11-25 06:51:34