2015-12-10 36 views
4

我們有一個Asp.net 4.5 mvc webapi,它有大約100個應用程序域,每個包含一個擴展名。IIS垃圾收集與許多應用程序域掛起

現在我們不時地掛着api。即使只返回一個字符串的狀態api沒有迴應,也沒有一個路由正在響應。

當它掛起時,該網站有大約120個線程(這是很正常的)和大約12 GB的RAM(這是不尋常的高)。

當我們做一個內存轉儲時,我們可以看到該網站是總是在垃圾回收中間

大多數情況下,我們發現大多數線程都處於堆棧,處理應用程序域之間的序列化並等待GC。 我們也有很多序列化,例如應用程序域通信以及與某些Redis緩存的組合

等待5分鐘時的事件不會結束。是否有任何已知的與許多應用程序域有關的垃圾回收問題?

由於該網站託管在IIS中,後臺GC應始終處於活動狀態。

當我看到在GC性能計數器的時間我可以看到GC幾乎總是運行

enter image description here

我可以看到,當網站掛了不斷的40%的時間在GC 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的內存工具查看哪些對象佔用內存。您會驚訝Web應用程序中的大對象堆中有多少個對象。當您向另一個Web服務發出請求時,它通常是大數據字節數組。查看是否可以彙集任何資源。 – Nikhil

回答

0

一些進一步的調查後的AppDomain沒有的原因。 我希望這可以節省其他人很多搜索:-)

我們在webapi進程中有一個大內存GraphDatabase(它使用大約30GB的RAM)。因此,我們的webapi項目和graphdatabase在同一過程中存在問題,並且GC從未成功結束該過程。使用非異步gc時,問題會更好,但有時會有一點滯後。

將此數據庫分離到自己的服務後,此行爲再也不會發生。

也有關於如何優化GC代碼,可以幫助