问题描述
我想调查一个真正讨厌的软件崩溃这是可能关系到一个托管堆损坏(因为垃圾收集过程中发生)。使用的WinDbg与(SOS)!gshandles命令我得到的东西像
I'm trying to investigate a really nasty software crash which is possibly related to a managed heap corruption (since it happens during a garbage collection). Using WinDbg with the (SOS) !gshandles command I get something like
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:
和我只是好奇,是什么固定异步一个正常的固定手柄和区别?我可以找到我的哪个手柄之一是异步呢?
我无法找到关于它的净任何信息和因为它似乎总是应用程序崩溃时,这个计数器是只有一个可能是相关的崩溃。但是,有一次它可能只是在垃圾收集过程中使用了一些内部的东西..
And I'm just curious, what is the difference between a "normal" pinned handle and an "async pinned" one? And can I find which one of my handles is the "async" one?I couldn't find any information on the net about it and since it seems that the application always crashes when this counter is exactly one it might be relevant to the crash. But then again it might just be some internal stuff used during the garbage collection..
推荐答案
异步固定手柄强烈与Windows重叠I / O相关。它支持异步读取与ReadFile的和WriteFile写,使用重叠的说法。设备驱动程序存储传递的缓冲区指针,可以直接读取/从程序的操作写入从/到缓冲区,完全是异步的。托管包装方法的BeginRead和BeginWrite。
Async pinned handles are strongly correlated with overlapped I/O in Windows. Which supports asynchronous reading and writing with ReadFile and WriteFile, using the OVERLAPPED argument. The device driver stores the passed buffer pointer and directly reads/writes from/to the buffer, entirely asynchronously from the program's operation. The managed wrapper methods are BeginRead and BeginWrite.
如果缓冲区中由GC堆上分配则它需要被固定,直到驱动程序完成利用缓冲器。具有GC移动缓冲器的,而的驱动程序工作的I / O传输是灾难性的,写将产生的垃圾,并会破坏GC堆,穿针需要prevent从缓冲区中读取而司机在使用它移动。
If the buffer is allocated in the GC heap then it needs to be pinned until the driver finishes using the buffer. Having the GC move the buffer while the driver is working on the I/O transfers is disastrous, writes would produce junk and reads would corrupt the GC heap, pinning is required to prevent the buffer from being moved while the driver is using it.
固定的对象是pretty不愉快,他们给垃圾收集器很难上班岩石周围的道路,当它压缩堆。这里的一个必要之恶,唯一可能的方式获得成功是离开固定的时间尽可能短量的缓冲区。
Pinned objects are pretty unpleasant, they give the garbage collector a hard time to work around the rock in the road when it compacts the heap. A necessary evil here, the only possible way to get ahead is to leave the buffer pinned for as short amount of time as possible.
异步固定手柄特殊标记,让CLR自动取消固定在I / O完成的缓冲区。尽可能快地,当I / O完成端口发出完成信号,因此不必等待客户端code来执行回调和取消固定缓冲区。其中当有大量线程池的线程在飞行中可能需要一段时间。它是一种微型优化趋于变成一个宏之一,当你有,比如说,处理成千上万的客户端请求的web服务器。
Async pinned handles are marked specially to allow the CLR to automatically unpin the buffer on I/O completion. As quickly as possible, when the I/O completion port signals completion and thus not having to wait for the client code to execute the callback and unpin the buffer. Which could take a while when there are lots of threadpool threads in flight. It is a micro-optimization that tends to turn into a macro one when you have, say, a web server that handles tens of thousands of client requests.
据只会用于类型System.Threading.OverlappedData,在mscorlib.dll一个内部类,CLR的具有专业知识,是针对Windows API函数使用本地OVERLAPPED结构的托管传真。对象
It is only ever used for objects of type System.Threading.OverlappedData, an internal class in mscorlib.dll that the CLR has special knowledge of and is the managed facsimile for the native OVERLAPPED structure that the Windows api functions use.
长话短说,你真正知道的是,有一个重叠I / O挂起,如果你看到的句柄计数1时崩溃。有任何本地code,它重叠I / O与没有固定的GC分配的缓冲区否则确实摧毁堆的好方法。你有相当多的固定手柄的BTW。
Long story short, all you really know is that there's an overlapped I/O pending if you see the handle count at 1 when it crashes. Having any native code that does overlapped I/O with gc allocated buffers that are not pinned is otherwise indeed a good way to destroy the heap. You have rather a lot of pinned handles btw.
这篇关于什么是"异步处理已固定"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!