2012-10-27 35 views
3

我想要更好地理解.NET線程模型。我聽過多次(最近在觀看這個視頻時看到這個視頻:AppFabric.tv - Threading with Jeff Richter),因爲.NET線程佔用了至少1MB的內存(因爲它們爲它們的堆棧預留了1MB)。 現在,我試着寫一些代碼來證明這一點,但我最終的結果就像爲什麼我的線程看起來佔用的內存少於1MB?

297 threads are using 42MB of memory 
298 threads are using 43MB of memory 
299 threads are using 40MB of memory 
300 threads are using 40MB of memory 

因此,線程似乎沒有使用的每個內存1MB。 我已盡最大努力重現上述視頻展示5分鐘的節目,但我似乎沒有得到相同的結果,我不明白爲什麼。由於內存消耗似乎有時在下降,我認爲線程必須退出或放在一個揹負的地方?或者,也許我沒有正確測量內存?

用於獲得上述結果的程序是這樣的:

class Program 
{ 
    static void Main(string[] args) 
    { 
     ManualResetEvent manualReset = new ManualResetEvent(false); 
     int createdThreads = 0; 
     try 
     { 
      while (true) 
      { 
       Thread t = new Thread(WaitOneEvent); 
       t.Start(manualReset); 
       createdThreads++; 
       Console.WriteLine("{0} threads are using {1}MB of memory", createdThreads, System.Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64/(1024 * 1024)); 
      } 
     } 
     catch (OutOfMemoryException) 
     { 
      Console.WriteLine("Out of memory at {0} threads", createdThreads); 
      System.Diagnostics.Debugger.Break(); 
      manualReset.Set(); 
     } 
    } 

    private static void WaitOneEvent(object eventObject) { 
     ((ManualResetEvent)eventObject).WaitOne(); 
    } 
} 

任何有識之士將不勝感激。

回答

2

您可能會喜歡使用VirtualMemorySize64(),但PrivateMemorySize64()

MS writes here

每個新線程或纖接收由 既保留和最初提交內存它自己的堆棧空間。保留的內存大小 表示虛擬內存中的總堆棧分配。 [012]最初的 承諾頁面在引用 之前不會使用物理內存; [...]

如OP的示例代碼線程什麼也不做,但等待信號,他們(棧)內存不使用物理內存中,因此不會被PrivateMemorySize64()予以考慮。

1

您的測量過於粗糙,無法準確跟蹤線程堆棧內存消耗。它測量不能與另一個進程共享的虛擬內存量。 .NET進程中唯一可共享的內存是代碼,本地Windows DLL,CLR,抖動以及由ngen.exe生成的任何本地映像(通常只有.NET框架程序集)。

其他一切都是私人記憶。 Jits代碼,加載器堆和垃圾收集堆是主要的塊。什麼是拋棄它,垃圾收集器會在虛擬內存分配時收縮。

您可以通過SysInternals的VMMap實用程序更好地瞭解虛擬內存使用情況。你會淹沒細節,但它顯示線程堆棧作爲一個單獨的類別。

相關問題