У нас есть веб-приложение Asp.net 4.5 mvc, в котором есть около 100 доменов приложений, каждый из которых содержит расширение.Коллекция мусора IIS висит с множеством областей приложения
Теперь время от времени у нас есть висит api. Ни один маршрут не отвечает даже статусу api, который возвращает только строку, не отвечает.
Когда он висит на сайте, имеет около 120 потоков (что вполне нормально) и около 12 ГБ оперативной памяти (что необычно высоко).
Когда мы делаем дамп памяти, мы можем видеть, что на сайте всегда в середине коллекции мусора.
В большинстве случаев мы видим, что большинство потоков зависает в стеке с кодом обработки сериализации между доменами приложения и ждет GC. У нас также есть много сериализаций, например, для связи домена приложения и в сочетании с некоторыми кешами redis
Событие при ожидании около 5 минут зависание не заканчивается. Существуют ли какие-либо известные проблемы коллекции мусора, связанные со многими доменами приложений?
Поскольку сайт размещен в IIS, фоновый GC всегда должен быть активным.
Когда я смотрю на время в счетчике GC Performance можно видеть, что GC почти всегда работает
Я могу видеть, что когда сайт висит его постоянно 40% времени в дс
Когда сайт находится в этом состоянии, я также вижу, что память постоянно увеличивается.
Любые намеки на то, что можно проверить или попытаться улучшить?
Возможно, это принесет пользу при обновлении среды выполнения до 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
Я считаю, каждый AppDomain должен быть своей собственной песочнице. Поэтому сбор мусора в одном AppDomain не должен замерзать другим. Используйте инструменты памяти RedGate или Jetbrain, чтобы увидеть, какие объекты занимают память. Вы будете удивлены, сколько объектов находится в кучке больших объектов в веб-приложении. Обычно это большие массивы байтов данных, когда вы делаете запрос на другой веб-сервис. Посмотрите, можно ли объединить ресурсы. – Nikhil