2013-09-06 23 views
8

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).

!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 

Trả lời

1

tôi nghi ngờ tailcalls là vấn đề (nếu không, tôi nghi ngờ rất nhiều người dùng F # sẽ gặp vấn đề này). Từ ngăn xếp cuộc gọi, có vẻ như mã của bạn đang chờ trên một phần quan trọng, dường như có nhiều khả năng trở thành nguồn gốc của vấn đề ... Bất kỳ ý tưởng nào về nguyên tắc đồng bộ hóa mã của bạn có thể dựa vào?

+0

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

+1

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

+0

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

1

Có lẽ hơi muộn và mặc dù vấn đề bạn mô tả có vẻ khác một chút so với cái tôi có, dấu vết cuộc gọi bạn đưa ra gợi ý có thể có một số điểm chung.

Bạn có thể tìm thêm thông tin chi tiết trong my answer cho câu hỏi của riêng mình, nhưng trong ngắn hạn nó đi đến sự kết hợp của Windows 7 và .NET 4.0-4.5 làm cho đệ quy đuôi trong F # có vấn đề, gây khóa quá mức. Cập nhật .NET thành 4.6 hoặc nâng cấp lên Windows 8 giải quyết được sự cố.

Ngoài ra, vì bạn đang gặp sự cố khi thu thập rác, bạn có thể muốn xem sử dụng server garbage collection. Đây là một trong những điều tôi đã làm trước khi tìm kiếm vấn đề trên và giải quyết một phần lớn các vấn đề hiệu suất mà chúng tôi gặp phải. Tất cả những gì cần thiết là những điều sau đây trong app.config của bạn:

<configuration> 
    ... 
    <runtime> 
    ... 
    <gcServer enabled="true"/> 
    ... 
    </runtime> 
    ... 
</configuration> 
Các vấn đề liên quan