WPF WCF MVVM OutOfMemoryException
I am working on this WCF-WPF app. I am frequently getting this error on an asynchronous XamDataGrid. Trying to make a WCF call and populate the Grid. I initially thought this is something to do with the large amounts of data returned from WCF and I made the call return data is much small pieces, by calling only for a category only. This error comes up randomly, not always on the same set of data. Reproducible enough in 15-20 tries.
I am running Windows XP (32bit), Dual Core, with 4GB of ram. When this exception is raised, client machine only uses about 2GB of RAM, and on the server W3WP is using only 800MB (of 6GB, 3 cores. Total memory use on server is ~2GB).
This is only happening on XP machines. Does not get this error on Windows 7 box.
Please guide me how to resolve this issue.
Thanks in advance
Event Viewer Logs this Message:
Event Type: Error
Event Source: .NET Runtime 2.0 Error Reporting
Event Category: None
Event ID: 5000
Date: 10/13/2010
Time: 10:50:07 AM
User: N/A
Computer: COMP-DC7800
Description:
EventType clr20r3, P1 appname.exe, P2 2.0.0.21872, P3 4cb0a1b1, P4 mscorlib, P5 2.0.0.0, P6 492b834a, P7 35df, P8 45, P9 system.outofmemoryexception, P10 NIL.
Below id the Exception details:
System.OutOfMemoryException was unhandled
Message="Exception of type 'System.OutOfMemoryException' was thrown."
Source="mscorlib"
StackTrace:
at System.IO.MemoryStream.set_Capacity(Int32 value)
at System.IO.MemoryStream.EnsureCapacity(Int32 value)
at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)
at System.Xml.XmlMtomReader.MimePart.GetBuffer(Int32 maxBuffer, Int32& remaining)
at System.Xml.XmlMtomReader.Initialize(Stream stream, String contentType, XmlDictionaryReaderQuotas quotas, Int32 maxBufferSize)
at System.Xml.XmlMtomReader.SetInput(Stream stream, Encoding[] encodings, String contentType, XmlDictionaryReaderQuotas quotas, Int32 maxBufferSize, OnXmlDictionaryReaderClose onClose)
at System.Xml.XmlMtomReader.SetInput(Byte[] buffer, Int32 offset, Int32 count, Encoding[] encodings, String contentType, XmlDictionaryReaderQuotas quotas, Int32 maxBufferSize, OnXmlDictionaryReaderClose onClose)
at System.ServiceModel.Channels.MtomMessageEncoder.MtomBufferedMessageData.TakeXmlReader()
at System.ServiceModel.Channels.BufferedMessageData.DoTakeXmlReader()
at System.ServiceModel.Channels.BufferedMessageData.GetMessageReader()
at System.ServiceModel.Channels.MessageHeaders.GetBufferedMessageHeaderReaderAtHeaderContents(IBufferedMessageData bu开发者_如何学运维fferedMessageData)
at System.ServiceModel.Channels.MessageHeaders.GetBufferedMessageHeaderReader(IBufferedMessageData bufferedMessageData, Int32 bufferedMessageHeaderIndex)
at System.ServiceModel.Channels.MessageHeaders.GetReaderAtHeader(Int32 headerIndex)
at System.ServiceModel.Channels.WsrmMessageInfo.Get(MessageVersion messageVersion, ReliableMessagingVersion reliableMessagingVersion, IChannel channel, ISession session, Message message, Boolean csrOnly)
at System.ServiceModel.Channels.ReliableDuplexSessionChannel.HandleReceiveComplete(IAsyncResult result)
at System.ServiceModel.Channels.ReliableDuplexSessionChannel.OnReceiveCompletedStatic(IAsyncResult result)
at System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
at System.ServiceModel.Channels.ReliableChannelBinder`1.InputAsyncResult`1.OnInputComplete(IAsyncResult result)
at System.ServiceModel.Channels.ReliableChannelBinder`1.InputAsyncResult`1.OnInputCompleteStatic(IAsyncResult result)
at System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
at System.ServiceModel.Channels.InputQueue`1.AsyncQueueReader.Set(Item item)
at System.ServiceModel.Channels.InputQueue`1.Dispatch()
at System.ServiceModel.Channels.InputQueue`1.OnDispatchCallback(Object state)
at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke2()
at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.OnSecurityContextCallback(Object o)
at System.Security.SecurityContext.Run(SecurityContext securityContext, ContextCallback callback, Object state)
at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke()
at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ProcessCallbacks()
at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.CompletionCallback(Object state)
at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.ServiceModel.Diagnostics.Utility.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
OutOfMemory exceptions can happen for a lot of reasons in general, and in web apps in particular.
First, if you're running on IIS, there are settings specific to IIS to limit memory, see here: http://blogs.msdn.com/b/pfedev/archive/2009/01/22/memory-based-recycling-in-iis-6-0.aspx
Depending on your configuration, pools, etc., these limits may not apply to .NET web applications.
Now, in ASP.NET, there is also a setting memoryLimit in the machine.config file that specifies the maximum allowed memory size, as a percentage of total system memory, that the worker process can consume before ASP.NET launches a new process and reassigns existing requests.
The default is 60%, which is equal to 1.2G on a 2G machine.
However,... whatever you configure, 800M is the practical limit for ASP.NET apps on a 32-bit machine, see a good explanation here: Understanding ASP.Net memory
The solution to avoid this is to change the way your system works and break it in smaller pieces.
That's why by default, WCF has been carefully configured with so many limits (see here for an extensive list: http://weblogs.asp.net/paolopia/archive/2008/03/23/wcf-configuration-default-limits-concurrency-and-scalability.aspx) ... which almost every developer tends to change and max-out as soon as he discovers it :-)
You won't be able to utilise that 4 GB of RAM with a 32 bit OS.
http://chris.pirillo.com/32-bit-windows-and-4gb-of-ram/
If your application is consuming more and more memory as you use it, you may want to look at your memory management. Look at implementing the IDisposable interface for classes with unmanaged resources. Also, avoid keeping references to objects once you've finished using them. Events are particularly bad for this.
How do events cause memory leaks in C# and how do Weak References help mitigate that?
You could also look at streaming to a temporary file instead of streaming to memory.
Feel Relieved to find the answer that Microsoft Screwed it up all... :). that blame almost saved my Job... Here is the story.. WCF has a default message size of 64kb. One cannot find the reason for this on MSDN.. and so when we need to change the max message size to whatever we want. The problem is that the threshold for LOH is 85000b. If the message size is more than that, the object will be placed in LOH, your profiler will show that the objects have collected.. but when you see the LOH size in Sysinternals Process Explorer, Process properties window, you still see that the memory using is increasing. At around 800MB, our mighty Dr Watson comes up and kick of this application. Apparently this is a known issue with WCF & .net 2.0
Issue still exists in .net 4.0 but Microsoft released a quickfix. Sysinternals Process explorer is the tool which helped diagnose this issue. See Screenshot
精彩评论