2015-09-28 68 views
64

Pod dużym obciążeniem nasza aplikacja sprawia, że ​​sprawny serwer przechodzi na 100% wykorzystanie procesora. Czytanie zrzutu procesu, patrząc na wątki, niektóre z nich są 10 minut w górę. Żaden z nich nie daje mi żadnego wglądu podczas używania! CLRStack. !xperf WinDBG C# .NET 4.5.2 Aplikacja - Opis zrzutu procesu

Uciekinier daje mi:

0:030> !runaway 
User Mode Time 
    Thread  Time 
    53:2e804  0 days 0:10:04.703 
    30:31894  0 days 0:07:51.593 
    33:47100  0 days 0:07:24.890 
    42:11e54  0 days 0:06:45.875 
    35:35e18  0 days 0:06:07.578 
    41:54464  0 days 0:05:49.796 
    47:57700  0 days 0:05:45.000 
    44:3c2d4  0 days 0:05:44.265 
    32:3898c  0 days 0:05:43.593 
    50:54894  0 days 0:05:41.968 
    51:5bc58  0 days 0:05:40.921 
    43:14af4  0 days 0:05:40.734 
    48:35074  0 days 0:05:40.406 
    ... 

Wywołanie DumpStack na jeden z tych wątków, otrzymuję:

0000001ab442f900 00007ff9ef4c1148 KERNELBASE!WaitForSingleObjectEx+0x94, calling ntdll!NtWaitForSingleObject 
0000001ab442f980 00007ff9e920beb2 clr!SVR::gc_heap::compute_new_dynamic_data+0x17b, calling clr!SVR::gc_heap::desired_new_allocation 
0000001ab442f9a0 00007ff9e90591eb clr!CLREventWaitHelper2+0x38, calling kernel32!WaitForSingleObjectEx 
0000001ab442f9b0 00007ff9e90e0d2c clr!WriteBarrierManager::UpdateEphemeralBounds+0x1c, calling clr!WriteBarrierManager::NeedDifferentWriteBarrier 
0000001ab442f9e0 00007ff9e9059197 clr!CLREventWaitHelper+0x1f, calling clr!CLREventWaitHelper2 
0000001ab442fa40 00007ff9e9059120 clr!CLREventBase::WaitEx+0x70, calling clr!CLREventWaitHelper 
0000001ab442fa70 00007ff9ef4c149c KERNELBASE!SetEvent+0xc, calling ntdll!NtSetEvent 
0000001ab442faa0 00007ff9e90ef1e1 clr!SVR::gc_heap::set_gc_done+0x22, calling clr!CLREventBase::Set 
0000001ab442fad0 00007ff9e90e9331 clr!SVR::gc_heap::gc_thread_function+0x8a, calling clr!CLREventBase::WaitEx 
0000001ab442fb00 00007ff9e92048e7 clr!SVR::gc_heap::gc_thread_stub+0x7a, calling clr!SVR::gc_heap::gc_thread_function 
0000001ab442fb60 00007ff9e91a0318 clr!Thread::CLRSetThreadStackGuarantee+0x48, calling kernel32!SetThreadStackGuaranteeStub 
0000001ab442fb90 00007ff9e91a01ef clr!Thread::CommitThreadStack+0x10, calling clr!Thread::CLRSetThreadStackGuarantee 
0000001ab442fbd0 00007ff9e910df0b clr!ClrFlsSetValue+0x57, calling kernel32!SetLastErrorStub 
0000001ab442fc00 00007ff9e92048dc clr!SVR::gc_heap::gc_thread_stub+0x6f, calling clr!_chkstk 
0000001ab442fc40 00007ff9f0d316ad kernel32!BaseThreadInitThunk+0xd 
0000001ab442fc70 00007ff9f1e54409 ntdll!RtlUserThreadStart+0x1d 

Co to jest mi powiedzieć? Widzę wiele wywołań do CLR, ale nie mogę zrozumieć, gdzie byłby problem. Po .reload (sugerowanym przez Thomasa) teraz widzę wywołania GC.

Aktualizacja 1

Po uruchomieniu xperf każdy w3wp.exe coś zużywa około 45% CPU. Filtrowanie według jednego z nich i grupowanie według funkcji zawiera funkcję oznaczoną jako "?" odpowiada za 13,62%, a pozostałe 2,67% lub mniej. Jak mogę się dowiedzieć, co to jest "?"?

Aktualizacja 2

Ran xperf ponownie, a funkcja JIT_MonEnterWorker_InlineGetThread_GetThread_PatchLabel jest odpowiedzialny za 12.31% wykorzystania procesora. "?" funkcja wciąż tam jest.

Grupowanie przez stos:

Line #, Stack, Count, Weight (in view), TimeStamp, % Weight 
2, |- ?!?, 501191, 501222.365294, , 35.51 
3, | |- clr.dll!JITutil_MonContention, 215749, 215752.552227, , 15.28 
4, | |- clr.dll!JIT_MonEnterWorker_InlineGetThread_GetThread_PatchLabel, 170804, 170777.100191, , 12.10 

Jak widać, te dwa są odpowiedzialne za ponad 27% zużycia procesora (dla każdego procesu, więc jest to istotne).

Aktualizacja 3

Po użyciu wpr.exe (sugestia przez @ magicandre1981):

wpr.exe -start cpu and wpr -stop result.etl 

I okazało się, że FormsAuthentication i niepotrzebne rozmowy do Ninject na ścieżce krytycznej były przyczyniając się do około 16% użycia procesora. Nadal nie rozumiem wątków trwających 10 minut lub dłużej.

Aktualizacja 4

Próbowano DebugDiag (sugestia @leppie) i tak potwierdza się, że nici wiszące są podobne do:

Thread ID: 53  Total CPU Time: 00:09:11.406  Entry Point for Thread: clr!Thread::intermediateThreadProc 
Thread ID: 35  Total CPU Time: 00:07:26.046  Entry Point for Thread: clr!SVR::gc_heap::gc_thread_stub 
Thread ID: 50  Total CPU Time: 00:07:01.515  Entry Point for Thread: clr!SVR::gc_heap::gc_thread_stub 
Thread ID: 29  Total CPU Time: 00:06:02.264  Entry Point for Thread: clr!SVR::gc_heap::gc_thread_stub 
Thread ID: 31  Total CPU Time: 00:06:41.281  Entry Point for Thread: clr!SVR::gc_heap::gc_thread_stub 

lub z powodu StackExchange.Redis:

DomainBoundILStubClass.IL_STUB_PInvoke(Int32, IntPtr[], IntPtr[], IntPtr[], TimeValue ByRef)+e1 
[[InlinedCallFrame] (StackExchange.Redis.SocketManager.select)] StackExchange.Redis.SocketManager.select(Int32, IntPtr[], IntPtr[], IntPtr[], TimeValueByRef) 
StackExchange.Redis.SocketManager.ReadImpl()+889 
StackExchange.Redis.SocketManager.Read()+66 

lub

[[GCFrame]] 
[[HelperMethodFrame_1OBJ] (System.Threading.Monitor.ObjWait)] System.Threading.Monitor.ObjWait(Boolean, Int32, System.Object) 
mscorlib_ni!System.Threading.Monitor.Wait(System.Object, Int32)+19 
StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[[System.__Canon, mscorlib]](StackExchange.Redis.Message, StackExchange.Redis.ResultProcessor`1, StackExchange.Redis.ServerEndPoint)+24f 
StackExchange.Redis.RedisBase.ExecuteSync[[System.__Canon, mscorlib]](StackExchange.Redis.Message, StackExchange.Redis.ResultProcessor`1, StackExchange.Redis.ServerEndPoint)+77 
[[StubHelperFrame]] 
StackExchange.Redis.RedisDatabase.SetMembers(StackExchange.Redis.RedisKey, StackExchange.Redis.CommandFlags)+ee 
+3

Coś, co czeka w 'WaitForSingleObjectEx()' nie zużywają CPU, ponieważ czeka i nie robi pracę. Wątki związane z impasem również nie zużywają procesora, ponieważ wszystkie będą czekały na zasoby. –

+1

@Thomas Każdy pomysł, w jaki sposób mogę uzyskać cokolwiek użytecznego z tego miejsca? Odnośnie liczby cyfr dla numeru wątku, ogólnie mam zarządzany kod runnig wątki z 3 cyfr. Nie wierzę, że to jest problem. –

+1

@ Thomas Po .Symfix nadal mam te same wartości. Już wcześniej mogłem zobaczyć kod zarządzany, więc nie naprawię go jako problemu z symbolem. –

Odpowiedz

-1

Powolna aplikacja może pochodzić z wolnego kodu. A może dzieje się tak z poziomu aplikacji.NET silnik

najpierw gdybyś sprawdził clr.dll jeśli masz problemy można go pobrać i zastąpić go na komputerze Else jeśli to nie ma żadnego problemu Spróbuj

Myślę, że powinieneś przejrzeć swoje kody aplikacji i pstryknąć każdy zakątek, który zajmuje dużo czasu i próbować zrównoważyć obciążenie operacji kodu pomiędzy procesorem i pamięcią RAM. pętle, inicjalizacji obiektu lub funkcji rekursji itd .. wszystko sprawia, że ​​obciążenie procesora Spróbuj przechowywanie przedmiotów Shard na statycznej lub ciągłych

+0

Nie można zrozumieć akapitu drugiego. Czytanie całego kodu tak dużej aplikacji nie jest takie łatwe, ale (tak) czasami może być jedyną opcją (przynajmniej te części, które są ciągle trafiane). O dzieleniu się obiektami za pomocą statycznego, jeśli dane zostaną unieważnione, masz problem z aktualizacją we wszystkich instancjach (które można rozwiązać, ale tak nie jest) –

+0

spróbuję tylko pomóc :) może trudno mi jest złapać ta sprawa – user3538022

Powiązane problemy