【问题标题】:What is an "Async Pinned Handle"?什么是“异步固定句柄”?
【发布时间】:2011-11-25 04:15:36
【问题描述】:

我正在尝试调查一个非常严重的软件崩溃,它可能与托管堆损坏有关(因为它发生在垃圾回收期间)。将 WinDbg 与 (SOS) !gchandles 命令一起使用,我得到类似

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:

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

【问题讨论】:

  • "但是你是对的,我会调查所有这些固定手柄的来源,数量相当高.." 你有什么有趣的事情吗?

标签: c# debugging windbg


【解决方案1】:

异步固定句柄与 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 挂起。拥有任何与 gc 分配的未固定的缓冲区重叠 I/O 的本机代码确实是破坏堆的好方法。顺便说一句,你有很多固定的句柄。

【讨论】:

  • 感谢您的回答,现在我明白了——我真的没有在其他任何地方找到这种信息!至于每次看到的崩溃,我发现这只是一个奇怪的巧合,在六次崩溃转储中,我恰好有 1 个“异步固定”和 137 个“固定”句柄。 137 比单个异步更奇怪,但可能只是因为我的程序总是在相同的状态下崩溃。但你是对的,我会调查所有这些固定手柄的来源,数量相当多。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-06
  • 2010-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多