Bir dizi eşzamanlı bağlantı etkin olduğunda hızlı bir şekilde düşme eğilimi olan bir windows hizmeti ile bir üretim sorununda hata ayıklamaya çalışıyorum. Bir çekirdek dökümü ve DebugDiag büyüsüyle, Preemptive GC devre dışı bırakılmış bir çok iş parçacığı işlerini tamamlayana kadar başlayamayan bekleyen bir GC operasyonu olduğunu anlayabildim. Eğer önleyici GC (konuları 26,27,28,29) ve bir devre dışı olan birkaç konuları görebilirsiniz Yani buradaCLR .tail komutu, önleyici GC'yi devre dışı bırakıyor mu?
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)
(thread: Burada
kusurlu konuları gösteren WinDbg örnek bir iplik çöplük 30) GC'yi gerçekleştirmek için bu ipleri beklemektedir.Google-fu'm beni benzer bir soruna benzeyen, yalnızca benim durumumda XML içermediğini açıklayan this blog post adresine yönlendiriyor. Ama kazmak için nerede olduğunu bilmek bana yeterli bilgi verdi ve sonunda ben devre önleyici GC ile parçacığı ortak özelliklerinden biri üst bu benzeyen bir yığın izleme olduğunu keşfetti:
ntdll!NtWaitForSingleObject+a
ntdll!RtlpWaitOnCriticalSection+e8
ntdll!RtlEnterCriticalSection+d1
ntdll!RtlpLookupDynamicFunctionEntry+58
ntdll!RtlLookupFunctionEntry+a3
clr!JIT_TailCall+db
...
DebugDiag da CriticalSection hakkında uyardı ve sadece bu yüzden JIT_TailCall
ile ipler RtlEnterCriticalSection
ile de sadece ipler Yani benim soru olduğunu olur: bu kilitlenme neden oluyor .tail
talimat aslında var mı? Ve eğer öyleyse: Bu konuda ne yapabilirim?
benim .fsproj dosyaları üzerinde tailcalls devre dışı bırakabilir ancak bunlardan en az biri FSharp.Core.dll
geliyor ve decompiler bazı spelunking .tail
öğretim varlığını teyit etmek görünüyor gibi görünüyor. Bu yüzden, proje yapılandırmasını değiştirmenin tüm .tail
yönergelerini kaldıracağını bilmiyorum.
Daha önce böyle bir şeyle uğraşan var mı?
Güncelleme: Kullanışlı olabilecek daha fazla bilgi. İşte
bu dökümü için!locks
çıktısı:
!locks
CritSec +401680 at 0000000000401680
WaiterWoken No
LockCount 0
RecursionCount 1
OwningThread 2340
EntryCount 0
ContentionCount bf
*** Locked
Scanned 1657 critical sections
Konu 2340 GC (yukarıda dahil kısmi listede ipliği 30) başlamıştır iplik.
ve !syncblk
sadece (başlatılmasını GC tutuyor rahatsız edici ise, kümelerin herhangi dahil değildir), zookeeper bir müşteriye ait olan ürün I tailcalls sorun şüphe
!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
Standart .Net Monitor sınıfları, ancak bunların gösterildikleri yığın izleri, kilitleri kullanan birkaç yerim var. bu kodun yakınında. Bu temelde liste işlemedir (bu yüzden List.iter, Map.find, vb.). İlginç olan şey, tüm ipliklerin az ya da çok aynı eylemi gerçekleştirmesidir, ancak 60 ya da daha fazlası aktif bağlantılardır, sadece 6'sı önleyici GC'yi devre dışı bırakmıştır – ckramer
'List.iter (fun _ ->. lock ..) xs 'yığın izlerini sizi 'List.iter' olarak gösterir mi? – t0yv0
Önleyici GC devre dışı bırakılan izlerde hiç kilitleme yok. Aynı zamanda farklı kuyruk optimizasyonlu fonksiyonlarda da meydana gelirler (bir durumda MapTreeInternal.mapi, bir diğeri de Primitives.Basics.List.iter, yine bir başka MapTreeModule.find'tir). Bu çağrıların hepsi de F # kayıt türleri üzerinde çalışıyor. Bu yüzden, burada yönetilmeyen kaynaklardan bahsetmemek için, burada tek kullanımlık örneklerin bile olmadığını söyleyebilirim. Tüm iş parçacıklarının ortak bir özelliği, bir Async TCP alma işlemi aracılığıyla çağrılır. Bunun bir şekilde dahil olup olmadığını bilmiyorum. – ckramer