Что такое "Async Pinned Handle"? - PullRequest
       11

Что такое "Async Pinned Handle"?

25 голосов
/ 26 сентября 2011

Я пытаюсь исследовать действительно неприятный сбой программного обеспечения, который, возможно, связан с повреждением управляемой кучи (так как это происходит во время сборки мусора). Используя 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 Ответ

28 голосов
/ 26 сентября 2011

Асинхронные закрепленные маркеры сильно коррелируют с перекрывающимся вводом / выводом в Windows. Который поддерживает асинхронное чтение и запись с ReadFile и WriteFile, используя аргумент OVERLAPPED. Драйвер устройства сохраняет переданный указатель буфера и напрямую считывает / записывает из / в буфер, совершенно асинхронно, от работы программы. Управляемые методы-оболочки - BeginRead и BeginWrite.

Если буфер выделен в куче ГХ, его необходимо закрепить до тех пор, пока драйвер не завершит использование буфера. Когда ГХ перемещает буфер , в то время как драйвер работает с передачей ввода-вывода, это губительно, записи приводят к нежелательной работе, а чтения приводят к повреждению кучи ГХ, закрепление необходимо для предотвращения перемещения буфера, пока водитель использует его.

Закрепленные объекты довольно неприятны, они затрудняют сборщику мусора вокруг камня на дороге, когда он уплотняет кучу. Необходимое зло здесь, единственный возможный способ продвинуться вперед - оставить буфер закрепленным на как можно более короткое время.

Асинхронные закрепленные маркеры помечены специально, чтобы позволить CLR автоматически откреплять буфер при завершении ввода-вывода. Как можно быстрее, когда порт завершения ввода / вывода сигнализирует о завершении и, таким образом, не нужно ждать, пока клиентский код выполнит обратный вызов и открепит буфер. Что может занять некоторое время, когда в потоке много потоков потоков. Это микрооптимизация, которая имеет тенденцию превращаться в макро, когда у вас есть, скажем, веб-сервер, который обрабатывает десятки тысяч клиентских запросов.

Он используется только для объектов типа System.Threading.OverlappedData, внутреннего класса в mscorlib.dll, о котором CLR обладает специальными знаниями и является управляемым факсимильным аппаратом для собственной структуры OVERLAPPED, которую используют функции API Windows.

Короче говоря, все, что вы на самом деле знаете, это то, что есть перекрывающийся ввод-вывод, ожидающий, если вы увидите количество дескрипторов в 1, когда оно падает. Любой собственный код, который выполняет перекрывающийся ввод-вывод с выделенными буферами gc, которые не закреплены, в противном случае действительно является хорошим способом уничтожения кучи. Кстати, у вас довольно много закрепленных ручек.

...