2009-07-22 56 views
1

我正在嘗試調試在GC中花費大量時間的.net Windows服務。gc_heap :: plan_phase究竟做了什麼?

收藏過程中使用的WinDbg我發現大部分的時間都花在:

00000000`0279e8e0 00000642`7f5368a3 mscorwks!WKS::gc_heap::plan_phase+0x50c 
00000000`0279ea90 00000642`7f94ef4e mscorwks!WKS::gc_heap::gc1+0x73 
00000000`0279eae0 00000642`7f51c259 mscorwks!WKS::gc_heap::garbage_collect+0x29e 
00000000`0279eb40 00000642`7f4eb56e mscorwks!WKS::GCHeap::GarbageCollectGeneration+0x199 
00000000`0279ebd0 00000642`7f4ea49d mscorwks!WKS::gc_heap::try_allocate_more_space+0x38e 
00000000`0279eca0 00000642`7f4e9cef mscorwks!WKS::GCHeap::Alloc+0x6d 
00000000`0279ecd0 00000642`7f9b35da mscorwks!FastAllocateObject+0xaf 

GEN0,第一代的模式,第二代的集合是合理的(100,10,1)

請注意該應用程序在x64上運行,並有一個非常大的堆:

Gen0 10M 
Gen1 26K 
Gen2 4,371M 
Large 3,500M 

注:我知道偉大的苔絲費蘭德斯博客。

回答

0

我會冒險猜測這是GC的標記階段,在這個階段它可以識別沒有根需要收集的物體。這只是一個猜測,因爲似乎沒有太多關於這方面的信息(我相信你知道)。

1

plan_phase是GC所做的一個階段。 氣相色譜有兩個階段 1-標記階段:在這個階段,所有的實時(可到達的對象)被標記爲追隨這些對象的根,這取決於集合類型(Gen0,1或2),我們標記某些部分堆(Gen0,1)或整個堆(Gen 2集合)

2-計劃階段:一旦我們標記了活體,我們知道關於堆的某些事情,例如比較活體對象的碎片和比例到堆大小..等等。 在計劃階段,我們決定什麼樣的GC決策是最好的,我們應該做一個壓縮GC(需要更多的時間,但是當你的碎片堆很高時會有所幫助),還是應該做一個徹底的決定(非常快,只需要一個自由對象列表)。

你有~4GB Gen2堆,這是一個很大的堆,可能需要一些時間來收集它。
我不確定你什麼時候提到「大時間」,你是什麼意思(定量的措施?),它是100ms,秒,分鐘?

+0

非常感謝您的回答。約5秒。我應該考慮一下我的堆碎片化的想法嗎? GC如何決定完成gen2集合而不是gen0。所有數據在進程啓動時加載,在執行期間根本不會改變 – 2009-07-22 20:33:51