2011-09-26 58 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