2010-04-06 27 views
27

我閱讀了.NET框架4目前的垃圾收集實現替換:背景和併發垃圾收集的區別?

.NET Framework 4中提供 後臺垃圾收集。這個 功能替代了先前版本中的併發垃圾 集合,並且 提供了更好的性能。

this page有一個解釋它是如何工作的,但我不知道我是否理解它。

在實際應用中,這種新的GC實現有什麼好處?它是否可以用於推動從3.5或以前到4.0的轉換?

回答

75

在這裏,Microsoft使用名稱「concurrent」和「background」來描述它在.NET中使用的GC的兩個版本。在.NET世界中,「後臺收集器」是對「併發收集器」的增強,因爲它對收集器運行時應用程序線程可以執行的操作有更少的限制。

基本的GC使用「停止世界」策略:應用程序線程從共同的堆中分配內存塊。 GC必須運行時(例如分配的塊太多,需要進行一些清理),全部應用(管理)線程停止。最後一個停止的線程運行GC,並在完成時釋放所有其他線程。世界停止的GC很容易實現,但會導致在用戶級別可以察覺的暫停。

微軟的「併發GC」是世代的:它只對堆的有限部分(他們稱之爲「世代0和1」)使用世界停止戰略。由於該部分很小,暫停時間很短(例如低於50ms),因此用戶不會注意到它們。堆的其餘部分用專用GC線程收集,該線程可同時運行與適用線程(因此名稱)

併發GC有一些限制。也就是說,有些時候GC線程必須對堆進行一定的排他控制。在這種情況下,應用程序線程只能從小的線程特定區域分配塊。具有較大需求的線程很快就會碰到主堆,當時它被GC線程鎖定。然後,分配線程必須阻塞,直到GC線程完成其鎖相階段。這再次誘發暫停。與停止世界的GC相比,停頓時間更短,並且這些暫停不會影響所有線程。然而,暫停。

「背景GC」是GC線程無需鎖定堆的增強型GC。這消除了前一段中描述的額外暫停;只有在收集年輕一代時才保留有限的停頓時間(微軟稱之爲「前景集合」)。

注意:有併發GC和背景GC的「隱藏成本」。爲了使這些GC正常工作,應用線程的內存訪問必須以一些非常特定的方式完成,這對性能有輕微的影響。此外,GC線程可能會對高速緩存造成不利影響,從而間接降低性能。對於不需要用戶交互的純粹計算任務而言,世界平臺收集器平均可以產生更好的性能(例如,20小時的計算將在19個小時內完成)。但這是一個邊緣案例,在大多數情況下,併發GC和後臺GC都更好。

+0

很好的解釋..但是如果你堅持使用主流的術語,它會更合適。託管線程/代碼等適用?那是什麼? – 2012-11-27 21:31:49

+8

應用程序線程是運行程序員編寫的代碼的線程(與隱藏管理線程相反,如果有的話)。 「管理」線程是運行託管代碼的線程(即不是用C或C++編寫的代碼)。這是_is_主流術語。 – 2012-11-27 23:28:49

1

由於垃圾收集,最主要的好處將是減少應用程序凍結,這本身可以被認爲是一個重大的改進。對於大多數應用程序來說,除非內存中有大量的長壽命對象,否則這種差異不會顯而易見。

這個改變也讓.NET在構建對時間敏感的應用程序(響應時間很重要)方面稍微更可行。極端的例子是汽車安全氣囊 - 您不希望軟件在需要充氣時忙於垃圾收集。 4.0中的更改減少了由GCing引起的凍結數量和長度,但不會完全刪除它們。

8

這裏是沒有污點和重視自我過度膨脹的感覺,現實世界的解釋:

在並行GC,你被允許在GC分配時間,但你允許啓動另一個GC而在GC中。這又意味着您在GC中允許分配的最大空間是您在一個區段(當前工作站模式下爲16 MB)上剩餘的任何空間減去已在那裏分配的任何空間。

在後臺模式不同的是,你允許開始新的GC(根0 + 1),而在一個完整的背景GC,這甚至允許你創建一個新的細分市場如果分配在必要。簡而言之,在您將所有內容分配給一個分段之前可能發生的阻塞現象不會再發生。

從苔絲達曼! http://blogs.msdn.com/b/tess/archive/2009/05/29/background-garbage-collection-in-clr-4-0.aspx