什么是“Async Pinned Handle”?

我正在尝试调查一个非常讨厌的软件崩溃,这可能与托管堆损坏有关(因为它发生在垃圾收集期间)。 使用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: 

而我只是好奇,“普通”固定手柄和“异步固定”手柄有什么区别? 我能找到哪个句柄是“异步”的吗? 我在网上找不到任何有关它的信息,因为当这个计数器正好与崩溃相关时,应用程序似乎总是崩溃。 但话说再说它可能只是垃圾收集过程中使用的一些内部东西。

异步固定句柄与Windows中的重叠I / O密切相关。 它使用OVERLAPPED参数支持使用ReadFile和WriteFile进行异步读写。 设备驱动程序存储传递的缓冲区指针,并直接从/向缓冲区读取/写入,完全与程序的操作异步。 托管包装器方法是BeginRead和BeginWrite。

如果缓冲区在GC堆中分配,则需要将其固定,直到驱动程序完成使用缓冲区。 让GC在驱动程序处理I / O传输移动缓冲区是灾难性的,写入会产生垃圾并且读取会破坏GC堆,需要固定以防止缓冲区在驱动程序使用时移动。

固定的物体非常令人不愉快,当它压缩堆时,它们使得垃圾收集器很难在路上的岩石周围工作。 这里是一个必要的邪恶,唯一可能的方法是让缓冲区尽可能短时间固定。

异步固定句柄专门标记为允许CLR在I / O完成时自动取消固定缓冲区。 尽可能快地,当I / O完成端口发出信号完成时,因此不必等待客户端代码执行回调并取消固定缓冲区。 在飞行中有很multithreading池线程时可能需要一段时间。 当你有一个处理成千上万个客户端请求的Web服务器时,它是一个微优化,往往会变成一个宏。

它只用于System.Threading.OverlappedData类型的对象,它是mscorlib.dll中的一个内部类,它是CLR特有的知识,是Windows api函数使用的本机OVERLAPPED结构的托管传真。

简而言之,您真正知道的是,如果您在崩溃时看到句柄计数为1,则会有重叠的I / O挂起。 拥有任何与未固定的gc分配缓冲区重叠I / O的本机代码确实是破坏堆的好方法。 你有相当多的固定手柄顺便说一下。