c# - 什么是 "Async Pinned Handle"?

标签 c# debugging windbg

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

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

最佳答案

异步固定句柄与 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 函数使用的 native OVERLAPPED 结构的托管传真。

长话短说,如果您在崩溃时看到句柄计数为 1,您真正知道的是有一个重叠的 I/O 未决。让任何 native 代码与 gc 分配的未固定缓冲区重叠 I/O 确实是销毁堆的好方法。顺便说一句,你有相当多的固定句柄。

关于c# - 什么是 "Async Pinned Handle"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7554927/

相关文章:

c++ - WinDBG 适用于从 Visual Studio 2015 保存的转储,但不适用于任务管理器。显示异常代码 "not found"

javascript - 将 C# 3D 数组移植到 JS 3D 数组

c# - 来自 DLL 的 Microsoft Visual Studio 2013 摘要

regex - 你如何用 sed "debug"一个正则表达式?

android - 为什么我在 Android Studio 中的 LLDB 调试器会跳过所有断点?

c++ - Windbg 设置依赖于调用堆栈的条件断点

c# - 使用 ASP.NET 表单例份验证,如何让图像显示在登录屏幕上?

c# - 在 UWP C# 中应用高通滤波器

java - 函数返回错误结果,但在具有相同字符串参数的调试器中返回良好结果

windows - 尝试使用 WinDbg : PEB is Paged Out, 分析转储文件不会加载符号