Tracking OutOfMemoryExceptions in C# code - c#

I am wondering if there is a tool that allows to track intermittent OutOfMemoryExceptions in C# code.
Ideally, I am looking for something that would detect OOM situation and once it happens, it would allow viewing the content of the managed heap.
I usually use WinDBG + SOS extension to view the heap state. The problem with this approach is that my problem is intermittent and I don't have a dump file when the exception happens. Also traversing the heap in WinDBG is not really user friendly experience.

Take a look at JetBrains dotTrace Profiler.

Is it that you want to track this exception or you want to identify the cause? I've use AQTime to hunt down memory leaks in managed/unmanaged code with a fair amount of success.

I would say that WinDbg + SOS is a good combination for this, but I'll give you that it is not the most attractive user experience.
My suggestion is that you set up your just in time debugger to create a crash dump and then use WinDbg to find the error.
Be aware that a crash dump for an out of memory exception may be huge.

Related

Any way to create a heap dump/histogram on OutOfMemoryException in C#?

Back in the Java world I was able to specify that the JVM should create a heap dump file on the first OutOfMemoryError. Is there anything equivalent in C#?
A heap dump would be ideal but I'd settle for a histogram.
If there's no way to do this automatically is there a way to hook this exception and then walk the heap manually?
You can use the MS Debugging tools ADPlus utility to get a process dump that includes the all the heaps.
Then using WinDBG.exe (also in debugging tools) you can use the !DumpHeap command to get all the data you need.
a little old but useful HOWTO link
I would use procdump because you can easily set it up before the crash to dump out the memory when the crash occurs. Then use windbg to look through the memory.
I would add that if it is not immediately obvious where the memory is going (using sos.dll tools command !dumpheap -stat), then you can use procdump to take a number of crash dumps at particular intervals so that you can track what memory is growing.
If you are not familiar with windbg and sos, you might want to check this out.

OutOfMemoryException - how to find memory leak?

I am developing a WinForm application. When running it for a long time wihout stopping, it suddenly raise a OutOfMemoryException. I don't know how to find the reason which causes this exception. I use Task Manager to see how much memory my application to use, I see that it only take 90000 KB while my RAM is 2GB. I don't know it is a memory leak error? If yes, I remember there are some .NET tools to help finding the memory leak.
Please help me. Thanks.
If you run your application through WinDbg you will be able to get a break down of all the objects in memory. A unusually large number will pin point the exact object that is causing this behavior.
You can follow these instructions
In a nut shell you do
Attach WinDbg to process
Issue .load SOS.dll command
Issue !dumpheap –stat to view managed objects
vmmap
A useful tool to see how much and what kind memory your process is using.
CLR Profiler
Provides a graphical view of the heap and what is holding on to what. It can be a bit slow, but if the leak is in the managed heap it will point out what types are the problem pretty easily. Here's a guide.
WinDBG
Like parapura mentioned, this is will let you find your leak, but there's a steep learning curve (and almost no gui).

How to solve Private bytes (Native memory) leak?

I'm developing a C# application which seems to have a leak.
I've used memory profiler and found that my
private bytes keep increasing but Bytes in all Heaps do not, which means that probably it's a native memory leak
Now I'm stuck, how do I find memory leaks in native code ?
First, if you have a dump of the leaking process, you can open it in WinDbg and issue the command :
!address -summary
if RegionUsageHeap is large, then it should be a native memory leak
if RegionUsageIsVAD, then it should be a .NET memory leak.
If this is a native leak, then you have 2 options :
Use DebugDiag : when prompt, choose 'Native Memory leak and Handle leak', choose the process you want to diagnose, and start working with the application until you experiment the memory leak. When complete, generate a full dump of the application (right click on the leak rule and select Full user dump). You can then analyze the generated dump (you'll need to have the symbols properly configured for this to work efficiently) : on 'advanced analysis' tab, select 'Memory pressure analyzers', open the dump file and press 'Start analysis'. This produces and html report you can analyze. You can refer to this page for a detailed walkthrough.
Use Application Verifier / WinDbg. In application verifier, select your application (.exe). In tests page, be sure Basics/Heaps is selected. In the lower pane, be sure 'Traces' is set to true. Once the configuration saved, re-run the application and generate a full dump when the leak occurs. Don't forget to clean application flags after the dump is generated. Then you can open the dump from within WinDbg, and investigate the leak with the help of '!heap' command. In particular, '!heap -l' will give you a list of leaked blocks, '!heap -p -a ' will show the details of a block, including the call stack of allocation.
If this is a .NET leak, there are third party tools to troubleshoot it. Starting from version 1.2, DebugDiag is also enable to perform .NET memory leak analysis (never tried this however).
Diagnosing native memory leaks in a managed application is (at least initially) very similar to diagnosing memory leaks in any other native application.
The way I normally approach these problems is to get the process to leak a large amount of memory, take a full process dump and then examine the dump to see what is using the most memory. For example if your process has a normal / initial private bytes of ~20MB but you can get your process to leak memory until it has ~200MB of private bytes, then there is a good chance that ~180MB of that memory is leaked - generally speaking whatever has the most memory allocated is where you should start looking.
Microsoft have a very useful tool called DebugDiag - initially developed for use in diagnosing memory leaks in IIS it is a very vesatile tool and very handy when dealing with memory issues. If you give it a crash dump it will perform some analysis and should (at the very least) tell you what module has allocated all of that memory, you can then start looking more specifically at how that module is used.
It's hard to give you a solid response without more information, but it sounds like the lib you are trying to use has a memory leak. You'll need to the lib with the appropriate tools, depending on the language it was written in. If you don't have the lib's source, contact the developers and have them fix the leak.
If you can post the name of the library and some of your source code (as well as the native method signatures), we might be able to give you some more specific advice.
private bytes in heaps managed by .net framework, you need use professional tool to analysis your source. such like use red gate memory profiler, find object created but not being disposed.
Usually I had the best results when hunting memory leaks using the ANTS Memory Profiler.
(Or other tools, personally I had best experiences with ANTS)

Determining where object allocations for objects on the heap occurred

Is there any tool such that it can get a heap dump from a running application and determine/group objects by where in source code they were created?
With no changes to source code and ideally something free.
What about .NET Memory Profiler from ANTS for example.
Maybe CLR Profiler.
The information is not available if you create a memory dump. In order to gather this, you have to monitor the process as it is running. You could launch the application via WinDbg and set breakpoints on all the constructors you're interested in (hopefully you don't want to look at each and every object).
If you create the breakpoint, so it dumps the stack you will have the point of creation for the object. However, keep in mind that the objects may move around during GC, which will make parring objects with stacks difficult (or even impossible in some cases).
Since your question is tagged with performance and profiling, I gather that you want to reduce memory allocations. Why not just look at the numbers of objects created (or possibly look at the largest objects created) by looking at the heap. Then go through the source code and figure out where such instances are created.
As others suggested memory profilers, Memprofiler is definitely the most advanced one (I've tried all existing .NET profilers). It has a 14 day trial.
You need a .NET memory profiler. These tools allow you to follow the object graphs on the garbage collected heap and can be very useful in identifying the sources of memory leaks. While they may not necessarily tell you the method where an object was created they will tell which instances of which classes are holding on to the objects and allow you to take differences of snap shots of the gc heap. They don't require modifications to source code. You may want to have a look at
What Are Some Good .NET Profilers?
Our QA teams use http://www.jetbrains.com/profiler/ for this kind of thing here when we run into bottlenecks. I'm pretty sure it will give you a list of allocations by method call. I'll go install it and check :)
Good old windbg + sos + pdb will make the dumping.
As for the "where in source code they were created" part - is impossible without instrumentation or injection.
The SOS Debugging Extension
How to use : http://msdn.microsoft.com/en-us/library/yy6d2sxs.aspx

CLR out of memory exceptions

We are getting a lot of out of memory exceptions and we can't seem to diagnose what is happening. It seems to be an issue that happens that will spike memory usage from 300 MB to over 1 GB in a matter of a few minutes. Now this is an IIS application and has three application domains running in separate thread pools.
We want to record when the memory exceptions are about to happen. So we can attempt to find a pattern. What is the best way to do this?
Is there a way to query the memory usage once a minute to see how high it is and send an alert email. Or maybe write an application that will monitor the CLR's memory usage? An ideas or a direction are more than welcome.
I am using Performance Monitor, but unless I am watching the process it is not that useful. I can only see what is was and when. I have also used the Red Gate Memory Profile tool, which is awesome by the way - only I cannot seem to hit upon the page or process that is causing the exception.
Install ADPlus on your server (it's part of the Windows Debugging Tools). When you start observing unusually high memory usage capture a memory dump using:
adplus -hang -p <PID> -quiet -o <dump file folder path>
<PID> is the process ID of the worker process which you can get from tasklist.exe.
If you're not always around when this issue occurs then you could automate capturing a memory dump using DebugDiag:
Use DebugDiag in leak tracking mode to trigger a process dump when either your Private or Virtual memory use reaches a certain threshold. That said, I've not always found this reliable.
Use DebugDiag in Crash Mode to capture a dump whenever CLR exceptions are thrown. You can used the Advanced Settings to configure DebugDiag to produce a full memory dump upon encountering a CLR exception of type System.OutOfMemoryException. This is more reliable and will definitely trigger. Only use Advanced Settings -> Exceptions, don't touch the Unconfigured First Chance Exceptions, leave this setting at None.
Once you have your memory dump, fire up WinDBG then load the dump file and load up SOS and start poking about.
Tess Ferrandez's blog is a great .NET debugging resource and she has plenty of articles and labs about how to track down memory leaks (these are archive.org links due to broken links):
If it is broken, fix it you should - memory issue articles
.NET Debugging Demos Lab 6:_Memory Leak
.NET Debugging Demos Lab 6:_Memory Leak - Review
.NET Debugging Demos Lab 7: Memory Leak
.NET Debugging Demos Lab 7: Memory Leak - Review
PerfMon counters are useful and can be used to confirm that you have a memory leak, but they don't tell the whole story. WinDBG and SOS are the tools you need to use to find out where your memory is being used.
Performance Monitor, aka Perfmon, is your friend - it is free and not intrusive and lightweight and can be safely run on production servers if you use less frequent sampling (every few seconds). The minimum it can do is to sample memory and CPU usage for your processes (w3wp.exe) and store them on a file.
Since you have not shared what you are doing in the application I can't suggest performance counters to store, but there are plenty in the ASP.NET and .NET and CLR.
Since you are getting a CLR out of memory exception, my hunch is GC is not working due to a pinned object or something. I doubt it is an unmanaged resource, such as bitmap, not being released although it could be.
Here are a list of counters I suggest:
.NET CLR Memory
GC Handles
Pinned Objects
Process for the w3wp.exe running your application
A couple, but mostly Working Set
ASP.NET
Managed Memory used
Try RedGate Memory Profiler. I suppose it works with ASP.NET sites (their performance profiler definitely does).
Use a memory profiler. There are a couple of good ones out there, e.g. JetBrains dotTrace or ANTS Memory Profiler from Red Gate. There were a couple of discussions here at Stack Overflow with lots of other tips and recommendations.
If you cannot afford a good profiler, you should use what Microsoft recommends in Production Debugging for .NET Framework Applications.
I would use ADPlus in "crash" mode to capture a memory dump when the exception occurs, and then WinDbg and SOS to figure out what's taking up all of the memory.
Use dotTrace or YourToolkit .NET where you can attach the profiler to the ASP process.
They have a trial version, so you don't need to spend money right away. Using these profilers you can select the timeline where memory starts increasing (you can see the memory usage visually in a graph), so it should be quite easy to select the range and understand what is causing the memory usage to shoot up so high.

Categories

Resources