Tôi đang cố gắng gỡ lỗi một sự cố sản xuất với dịch vụ cửa sổ có xu hướng giảm nhanh chóng khi một số kết nối đồng thời đang hoạt động. Thông qua sự kỳ diệu của một bãi chứa lõi và DebugDiag tôi đã có thể phát hiện ra rằng có một hoạt động GC đang chờ giải quyết, mà không thể bắt đầu cho đến khi một số chủ đề với Preemptive GC vô hiệu hóa hoàn thành công việc của họ.Lệnh CLR .tail có vô hiệu hóa GC ưu tiên không?
Đây là một bãi chứa thread mẫu từ WinDbg hiển thị chủ đề vi phạm:
26 6e 1444 00..440 8009222 Disabled 00..200:00..f88 00..7a0 0 MTA (Threadpool Completion Port)
27 c1 1a0c 00..fe0 8009222 Disabled 00..e90:00..f88 00..7a0 0 MTA (Threadpool Completion Port)
28 b5 17bc 00..6f0 8009222 Disabled 00..268:00..f88 00..7a0 0 MTA (Threadpool Completion Port)
29 89 1f1c 00..ab0 8009222 Disabled 00..a30:00..f88 00..7a0 0 MTA (Threadpool Completion Port)
30 ac 2340 00..f70 8009220 Disabled 00..d00:00..d08 00..7a0 1 MTA (GC) (Threadpool Completion Port)
31 88 1b64 00..fd0 8009220 Enabled 00..b28:00..b48 00..7a0 0 MTA (Threadpool Completion Port)
Vì vậy, ở đây bạn có thể thấy một vài chủ đề mà có GC ưu tiên vô hiệu hóa (bài 26,27,28,29) và một (Chủ đề 30) đang chờ đợi các chủ đề đó để thực hiện GC.
Google-fu của tôi dẫn tôi đến this blog post mô tả những gì giống như một vấn đề tương tự, chỉ trong trường hợp của tôi không có XML liên quan. Nó đã cho tôi đủ thông tin để biết được nơi để đào mặc dù, và cuối cùng tôi phát hiện ra rằng một trong những đặc điểm chung của các chủ đề với GC ưu tiên vô hiệu hóa là một vết đống trông như thế này ở đầu trang:
ntdll!NtWaitForSingleObject+a
ntdll!RtlpWaitOnCriticalSection+e8
ntdll!RtlEnterCriticalSection+d1
ntdll!RtlpLookupDynamicFunctionEntry+58
ntdll!RtlLookupFunctionEntry+a3
clr!JIT_TailCall+db
...
DebugDiag cũng cảnh báo tôi về CriticalSection, và nó chỉ như vậy sẽ xảy ra rằng các chủ đề với JIT_TailCall
là cũng là chủ đề duy nhất với RtlEnterCriticalSection
vì vậy, câu hỏi của tôi là: là nó trong thực tế, .tail
hướng dẫn đó gây ra bế tắc này? Và nếu có: Tôi có thể làm gì với nó?
Tôi có thể tắt ổ đĩa trên tệp .fsproj của mình nhưng có vẻ như ít nhất một trong số này đến từ FSharp.Core.dll
và một số trò chơi trong trình giải mã dường như xác nhận sự tồn tại của hướng dẫn .tail
. Vì vậy, tôi không biết rằng chaning cấu hình dự án sẽ loại bỏ tất cả các hướng dẫn .tail
.
Có ai bị xử lý như thế này trước đây không?
Cập nhật: Một số thông tin khác có thể hữu ích.
Dưới đây là sản phẩm của !locks
để tống ra này:
!locks
CritSec +401680 at 0000000000401680
WaiterWoken No
LockCount 0
RecursionCount 1
OwningThread 2340
EntryCount 0
ContentionCount bf
*** Locked
Scanned 1657 critical sections
Chủ đề năm 2340 là các chủ đề đã bắt đầu GC (Chủ đề 30 trong danh sách phần tôi bao gồm ở trên).
Và !syncblk
chỉ đang hiển thị các mặt hàng thuộc sở hữu của khách hàng Zookeeper (trong đó, trong khi gây phiền nhiễu, không tham gia vào bất kỳ của ngăn xếp được giữ GC từ khởi đầu)
!syncblk
Index SyncBlock MonitorHeld Recursion Owning Thread Info SyncBlock Owner
11 0000000019721a38 1 1 0000000019766e20 638 7 0000000000fb2950 System.Collections.Generic.LinkedList`1[[ZooKeeperNet.Packet, ZooKeeperNet]]
Waiting threads:
18 0000000019721c68 1 1 000000001ae71420 8ac 13 00000000012defc8 System.Collections.Generic.LinkedList`1[[ZooKeeperNet.Packet, ZooKeeperNet]]
Waiting threads:
-----------------------------
Total 64
CCW 0
RCW 0
ComClassFactory 0
Free 5
Tôi có một vài địa điểm đang sử dụng khóa, vì vậy tiêu chuẩn .Net Lớp màn hình, nhưng dấu vết ngăn xếp nơi chúng hiển thị là không nơi gần mã đó. Đây là cơ bản tất cả các danh sách xử lý (do đó List.iter, Map.find, vv). Điều thú vị là tất cả các chủ đề đang thực hiện nhiều hơn hoặc ít hơn cùng một hành động, nhưng trong số 60 hoặc hơn là các kết nối hoạt động, chỉ có 6 đã tắt GC trước – ckramer
Có thể là 'List.iter (vui _ ->. khóa ..) xs' sẽ làm cho các dấu vết ngăn xếp giới thiệu bạn đến 'List.iter'? – t0yv0
Tôi không có bất kỳ ổ khóa nào trong dấu vết đang hiển thị GC bị tắt trước. Chúng cũng xuất hiện trong các hàm tối ưu hóa đuôi khác nhau (vì vậy trong một trường hợp là MapTreeInternal.mapi, một hàm khác là Primitives.Basics.List.iter, Còn một hàm khác trong MapTreeModule.find). Tất cả các cuộc gọi này đều hoạt động trên các loại bản ghi F #, vì vậy theo như tôi có thể nói, thậm chí không có bất kỳ trường hợp dùng một lần nào tại đây, chưa kể đến các tài nguyên không được quản lý. Một điều tất cả các chủ đề có điểm chung là chúng được gọi thông qua một hoạt động nhận Async TCP. Tôi không biết nếu đó là bằng cách nào đó có liên quan hoặc không tho. – ckramer