2011-09-26 31 views
19

Tôi đang cố gắng để điều tra một vụ tai nạn phần mềm thực sự khó chịu mà có thể liên quan đến một tham nhũng heap được quản lý (vì nó xảy ra trong một bộ sưu tập rác). Sử dụng WinDbg với (SOS)! Gshandles lệnh tôi nhận được một cái gì đó giống như"Xử lý được ghim" là gì?

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: 

Và tôi chỉ tò mò, sự khác biệt giữa một tay cầm gắn "bình thường" và "async gắn" một là bao nhiêu? Và tôi có thể tìm thấy cái nào trong tay cầm của tôi là cái "không đồng bộ" không? Tôi không thể tìm thấy bất kỳ thông tin nào trên mạng về nó và vì dường như ứng dụng luôn bị treo khi bộ đếm này chính xác là ứng dụng có thể liên quan đến sự cố. Nhưng sau đó lại có thể chỉ là một số nội dung được sử dụng trong quá trình thu gom rác ..

+0

"Nhưng bạn nói đúng, tôi sẽ điều tra nơi tất cả các chốt được ghim đến từ đó, con số này khá cao .." bạn có thấy điều gì thú vị không? – stej

Trả lời

23

Tay cầm được ghim không đồng bộ có liên quan chặt chẽ với I/O chồng lên nhau trong Windows. Hỗ trợ đọc và viết không đồng bộ với ReadFile và WriteFile, sử dụng đối số OVERLAPPED. Trình điều khiển thiết bị lưu trữ con trỏ đệm đã truyền và trực tiếp đọc/ghi từ/đến bộ đệm, hoàn toàn không đồng bộ từ hoạt động của chương trình. Các phương thức wrapper được quản lý là BeginRead và BeginWrite.

Nếu bộ đệm được phân bổ trong vùng đệm GC thì nó cần được ghim cho đến khi trình điều khiển kết thúc bằng bộ đệm. Có GC di chuyển bộ đệm trong khi trình điều khiển đang hoạt động trên chuyển I/O là tai hại, ghi sẽ tạo ra rác và đọc sẽ hỏng heap GC, ghim là cần thiết để ngăn không cho bộ đệm bị di chuyển trong khi trình điều khiển đang sử dụng nó .

Đối tượng được ghim là khá khó chịu, chúng cung cấp cho người thu gom rác một thời gian khó khăn để làm việc xung quanh tảng đá trên đường khi nó nén đống. Một điều ác cần thiết ở đây, cách duy nhất có thể để đi trước là để lại bộ đệm được ghim trong một khoảng thời gian ngắn nhất có thể.

Tay cầm được ghim không đồng bộ được đánh dấu đặc biệt để cho phép CLR tự động bỏ ghim bộ đệm khi hoàn thành I/O. Nhanh nhất có thể, khi cổng hoàn thành I/O báo hiệu hoàn thành và do đó không phải đợi mã máy khách thực hiện cuộc gọi lại và bỏ ghim bộ đệm. Mà có thể mất một lúc khi có rất nhiều chủ đề threadpool trong chuyến bay. Đó là một tối ưu hóa vi mô có xu hướng biến thành một macro khi bạn có, một máy chủ web xử lý hàng chục nghìn yêu cầu của máy khách.

Nó chỉ được sử dụng cho các đối tượng kiểu System.Threading.OverlappedData, một lớp nội bộ trong mscorlib.dll mà CLR có kiến ​​thức đặc biệt và là bản fax được quản lý cho cấu trúc OVERLAPPED gốc mà các hàm api của Windows sử dụng.

Ngắn câu chuyện ngắn, tất cả những gì bạn thực sự biết là có một I/O chồng lên nhau đang chờ xử lý nếu bạn thấy số lượng xử lý là 1 khi nó bị lỗi. Có bất kỳ mã nguồn gốc nào chồng chéo I/O với các bộ đệm được cấp phát gc không được ghim nếu không thực sự là một cách tốt để phá hủy heap. Bạn có khá nhiều chốt xử lý btw.

+0

Cảm ơn câu trả lời của bạn, bây giờ tôi hiểu - tôi thực sự không tìm thấy loại thông tin này ở bất kỳ nơi nào khác! Đối với vụ tai nạn cho mỗi xem tôi thấy nó chỉ là một sự trùng hợp kỳ lạ rằng trong nửa tá bãi sụp đổ tôi có * chính xác * 1 "Async Pinned" và 137 "Pinned" xử lý. 137 thậm chí còn lạ lùng hơn là một phần mềm không đồng bộ nhưng sau đó lại có thể chỉ vì chương trình của tôi luôn luôn bị treo trong cùng một trạng thái. Nhưng bạn là đúng, tôi sẽ điều tra nơi tất cả các xử lý pinned đến từ, số lượng khá cao .. Cảm ơn một lần nữa. – floyd73

Các vấn đề liên quan