Подтвердить что ты не робот

Что такое "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:

И мне просто интересно, какая разница между "нормальным" закрепленным ручкой и "асинхронным"? И могу ли я найти, какая из моих ручек - "асинхронная"? Я не мог найти в сети никакой информации об этом, и, поскольку кажется, что приложение всегда сбой, когда этот счетчик точно один, он может иметь отношение к сбою. Но опять-таки это может быть просто внутренний материал, используемый во время сбора мусора.

4b9b3361

Ответ 1

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

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

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

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

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

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