2011-09-26 72 views
19

我試圖調查一個真正令人討厭的軟件崩潰,這可能與託管堆損壞相關(因爲它發生在垃圾回收期間)。使用的WinDbg與(SOS)!gshandles命令我得到的東西像什麼是「異步固定手柄」?

0:000> !gchandles 
GC Handle Statistics: 
Strong Handles: 259 
Pinned Handles: 137 
Async Pinned Handles: 1 
Ref Count Handles: 79 
Weak Long Handles: 197 
Weak Short Handles: 650 
Other Handles: 0 
Statistics: 

而我只是好奇,是什麼「固定異步」一個「正常」的固定手柄和區別?我能找到哪一個手柄是「異步」手柄嗎? 我在網上找不到任何有關它的信息,因爲當這個計數器剛好是1時,應用程序總是崩潰,它可能與崩潰有關。但是,它可能只是在垃圾回收期間使用的一些內部材料。

+0

「但你是對的,我會調查所有這些固定手柄來自哪裏,數量相當高..」你有什麼感興趣的嗎? – stej

回答

23

異步固定手柄與Windows中的重疊I/O密切相關。它使用OVERLAPPED參數支持使用ReadFile和WriteFile進行異步讀寫。設備驅動程序存儲傳遞的緩衝區指針,並直接從緩衝區讀取/寫入緩衝區,與程序的操作完全不同步。託管包裝方法是BeginRead和BeginWrite。

如果在GC堆中分配了緩衝區,則需要將其固定到驅動程序完成使用緩衝區之前。讓GC移動緩衝區驅動程序正在處理I/O傳輸是災難性的,寫入會產生垃圾並且讀取會破壞GC堆,需要鎖定以防止驅動程序在使用緩衝區時移動緩衝區。

固定對象非常不愉快,當垃圾收集器壓縮堆時,垃圾收集器很難在路上晃動。這裏是一個必要的罪惡,唯一可行的方法就是儘可能短地放置緩衝區。

異步固定手柄被特別標記爲允許CLR在I/O完成時自動解除鎖定緩衝區。儘快完成I/O完成端口,從而不必等待客戶端代碼執行回調並取消固定緩衝區。在飛行中有很多線程池線程可能需要一段時間。這是一種微型優化,當你擁有一個處理成千上萬個客戶端請求的Web服務器時,它往往會變成一個宏觀優化。

它僅用於System.Threading.OverlappedData類型的對象,該類型是mscorlib.dll中的一個內部類,CLR具有特殊的知識,並且是Windows API函數使用的本機OVERLAPPED結構的託管傳真。長期以來,所有您真正知道的是,如果您在處理崩潰時看到1的句柄計數,那麼存在重疊的I/O掛起問題。有任何本地代碼重疊I/O與gc分配的緩衝區沒有釘住否則確實是一個很好的方式來摧毀堆。你有很多固定手柄順便說一句。

+0

感謝您的回答,現在我明白了 - 我確實沒有在其他地方找到這種信息!至於每次看到的崩潰,我發現這只是一個奇怪的巧合,在六個崩潰轉儲中,我有* * *「異步固定」和137個「固定」處理。更奇怪的是,單獨的異步版本可能只是因爲我的程序總是在相同的狀態下崩潰。但你是對的,我會調查所有這些固定手柄來自哪裏,數量相當高。再次感謝。 – floyd73