2015-12-10 1 views
4

У нас есть веб-приложение Asp.net 4.5 mvc, в котором есть около 100 доменов приложений, каждый из которых содержит расширение.Коллекция мусора IIS висит с множеством областей приложения

Теперь время от времени у нас есть висит api. Ни один маршрут не отвечает даже статусу api, который возвращает только строку, не отвечает.

Когда он висит на сайте, имеет около 120 потоков (что вполне нормально) и около 12 ГБ оперативной памяти (что необычно высоко).

Когда мы делаем дамп памяти, мы можем видеть, что на сайте всегда в середине коллекции мусора.

В большинстве случаев мы видим, что большинство потоков зависает в стеке с кодом обработки сериализации между доменами приложения и ждет GC. У нас также есть много сериализаций, например, для связи домена приложения и в сочетании с некоторыми кешами redis

Событие при ожидании около 5 минут зависание не заканчивается. Существуют ли какие-либо известные проблемы коллекции мусора, связанные со многими доменами приложений?

Поскольку сайт размещен в IIS, фоновый GC всегда должен быть активным.

Когда я смотрю на время в счетчике GC Performance можно видеть, что GC почти всегда работает

enter image description here

Я могу видеть, что когда сайт висит его постоянно 40% времени в дс enter image description here

Когда сайт находится в этом состоянии, я также вижу, что память постоянно увеличивается.

Любые намеки на то, что можно проверить или попытаться улучшить?

Возможно, это принесет пользу при обновлении среды выполнения до 4.5.2? так:

ntdll!NtWaitForSingleObject+a 
KERNELBASE!WaitForSingleObjectEx+94 
clr!CLREventWaitHelper2+38 
clr!CLREventWaitHelper+1f 
clr!CLREventBase::WaitEx+70 
clr!SVR::gc_heap::wait_for_gc_done+55 
clr!SVR::WaitLonger+9e 
clr!SVR::GCHeap::Alloc+224 
clr!JIT_New+142 
[[HelperMethodFrame]] 
mscorlib_ni!System.Runtime.Serialization.ObjectManager.RegisterFixup(System.Runtime.Serialization.FixupHolder, Int64, Int64)+d1 
mscorlib_ni!System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()+128 
mscorlib_ni!System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(System.Runtime.Remoting.Messaging.HeaderHandler, System.Runtime.Serialization.Formatters.Binary.__BinaryParser, Boolean, Boolean, System.Runtime.Remoting.Messaging.IMethodCallMessage)+db 
mscorlib_ni!System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(System.IO.Stream, System.Runtime.Remoting.Messaging.HeaderHandler, Boolean, Boolean, System.Runtime.Remoting.Messaging.IMethodCallMessage)+1bf 
mscorlib_ni!System.Runtime.Remoting.Channels.CrossAppDomainSerializer.DeserializeObject(System.IO.MemoryStream)+f8 
mscorlib_ni!System.Runtime.Remoting.Messaging.SmuggledMethodCallMessage.FixupForNewAppDomain()+de8a4e 
mscorlib_ni!System.Runtime.Remoting.Channels.CrossAppDomainSink.DoDispatch(Byte[], System.Runtime.Remoting.Messaging.SmuggledMethodCallMessage, System.Runtime.Remoting.Messaging.SmuggledMethodReturnMessage ByRef)+33 
mscorlib_ni!System.Runtime.Remoting.Channels.CrossAppDomainSink.DoTransitionDispatchCallback(System.Object[])+92 
clr!CallDescrWorkerInternal+83 
clr!CallDescrWorkerWithHandler+4a 
clr!DispatchCallDebuggerWrapper+1f 
clr!DispatchCallSimple+88 
clr!ThreadNative::InternalCrossContextCallback+2ea 
[[ContextTransitionFrame]] 
[[HelperMethodFrame_PROTECTOBJ] (System.Threading.Thread.InternalCrossContextCallback)] System.Threading.Thread.InternalCrossContextCallback(System.Runtime.Remoting.Contexts.Context, IntPtr, Int32, System.Threading.InternalCrossContextDelegate, System.Object[]) 
mscorlib_ni!System.Runtime.Remoting.Channels.CrossAppDomainSink.DoTransitionDispatch(Byte[], System.Runtime.Remoting.Messaging.SmuggledMethodCallMessage, System.Runtime.Remoting.Messaging.SmuggledMethodReturnMessage ByRef)+a0 
mscorlib_ni!System.Runtime.Remoting.Channels.CrossAppDomainSink.SyncProcessMessage(System.Runtime.Remoting.Messaging.IMessage)+15d 
mscorlib_ni!System.Runtime.Remoting.Proxies.RemotingProxy.CallProcessMessage(System.Runtime.Remoting.Messaging.IMessageSink, System.Runtime.Remoting.Messaging.IMessage, System.Runtime.Remoting.Contexts.ArrayWithSize, System.Threading.Thread, System.Runtime.Remoting.Contexts.Context, Boolean)+8c 
mscorlib_ni!System.Runtime.Remoting.Proxies.RemotingProxy.InternalInvoke(System.Runtime.Remoting.Messaging.IMethodCallMessage, Boolean, Int32)+22c 
mscorlib_ni!System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(System.Runtime.Remoting.Proxies.MessageData ByRef, Int32)+1f4 
clr!CTPMethodTable__CallTargetHelper3+12 
clr!CallTargetWorker2+74 
clr!CTPMethodTable::OnCall+1fb 
clr!TransparentProxyStub_CrossContextPatchLabel+a 
[[TPMethodFrame] (SR.BusPortal.Providers.Contract.Common.IAdapterSearcher.SearchAsync)] SR.BusPortal.Providers.Contract.Common.IAdapterSearcher.SearchAsync(SR.BusPortal.Providers.Contract.Common.AdapterSearchParameters) 
SR.BusPortal.Search.Steps.SearchStepOneWay`2+<SearchOneWayAsync>d__3[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].MoveNext()+73 
+0

Я считаю, каждый AppDomain должен быть своей собственной песочнице. Поэтому сбор мусора в одном AppDomain не должен замерзать другим. Используйте инструменты памяти RedGate или Jetbrain, чтобы увидеть, какие объекты занимают память. Вы будете удивлены, сколько объектов находится в кучке больших объектов в веб-приложении. Обычно это большие массивы байтов данных, когда вы делаете запрос на другой веб-сервис. Посмотрите, можно ли объединить ресурсы. – Nikhil

ответ

0

После некоторого дальнейшего расследования AppDomains не были причиной. Надеюсь, это сэкономит кому-то много поиска :-)

У нас была большая память MemoryDatabase (которая использовала около 30 ГБ ОЗУ) в процессе webapi. В результате наш проект webapi и графическая база данных в том же процессе были проблематичными, и GC никогда не удавалось завершить этот процесс. С неасинхронным gc проблема была лучше, но несколько раз лаги.

После разделения этой базы данных на свою службу это поведение никогда не повторялось.

Есть также много сообщений о том, как оптимизировать код для GC, который может помочь

Смежные вопросы