Memory leak - any guesses where it can be - c#

I'm working on .Net project (windows service) and I found memory leak. Using ANTS Memory profiler, I've determined - root cause is in unmanaged memory scope. But I don't use any COM/COM+ or p/invoke - pure .Net (DataAcces - Fluent nHibernate, Automapper, WCF)..
Hypothetically, what can be reason? How can I find bottleneck.. I'm interested in any kind of experience, who've faced and solved such kind of isseus
A bit more details:
I know how objects are disposing (and do it right)
I (almost) don't use events
I'm using timers
I'm using multithreading (but it's rather parallelism)
My application is not stateless - I'm tracking objects during their life-cycle

About Memory Leaks
Generally Speaking Memory Leaks still can exist in .net. (Sort of, not all of these are text book memory leaks per se) As in things get stuck in generation 2 garbage collection or when not disposing of object that inherit from IDisposable or for that matter Streams, Events, SQL connections that stay open and mess with you connection pool.While I am not an expert in the matter I will point you to a couple of places that may help you on your quest.
Memory Management Fundementals
Detecting Memory Leaks in .NET
While you are at it Groking the way that garbage collection works helps in this sort of endevor a great deal. Start with something like The Fundementals of Garbage Collection for a general mental picture of just what the heck is going on with all that .NET magic behind the scenes.
On the COM Stuff
Inherent in .NET there are many things that are just simply com and or win32 wrappers calling PInvoke behind the scenes. If gettin down and dirty with insides is what you are wanting then I'd recommend you look at a Decompiler (like IL Spy) where you suspect the leaky code.
Check this out for a deeper discussion on all the wrapper related stuff.
Is .NET A Wrapper Around Win32?

Related

What could i implement to learn .net GC in depth

I know some details of how it works by Richter's book, but i want to "feel" it in practice. I see some variants:
Write my own GC implementation by .NET standard (just kidding, it is too hardcore to do it on my own :)
Study MONO implementation of GC - it have some pluses (for example i could analyze some cases with debugger), but on the other hand it is not so different from reading a book. And by the way as far as i know MONO implementation really differs from Microsoft's one (correct me if i am wrong).
So, any suggestions?
Well, you could write a resource intensive server application, that will give you the gist of what GC does under significant load. You can pick anything you want, ideally something like a web server, an MMO server, etc.
You will get to see how the GC manages the managed heap under complicated circumstances (asynchronous sockets in particular make GC very unhappy, thanks to their use of pinned handles), and you can experiment with how to best allocate different kinds of memory resources to make GCs job as easy as possible.
And you could write your own GC, stupid GC is not that hard.

C# Usage of GC and how to trace a Memory Leak

I have a large C# server application, I'm interested in learning how the GC class works, and in particular what actions should I take to determine the source of a possible memory leak.
Are there any books on the subject, or is it not really that ellaborate?
There are plenty of sources you can study.
I hope you don't miss basics:
CLR via C# 3rd Edition by Jeffrey Richter
I think before you go with details about GC, try to understand how IDisposable and resource management is handled:
Dispose, Finalization, and Resource Management. It pretty old but still awesome.
GC specific:
Garbage Collection / Fundamentals of Garbage Collection
Maoni's WebLog (Maoni Stephens is a software developer who spends her time implementing .NET's GC. In fact, she's been working on the GC since the early days of .NET.)
Video: Maoni Stephens and Andrew Pardoe: CLR 4 Garbage Collector - Inside Background GC
Video: Erik Meijer and Patrick Dussud - Inside Garbage Collection
Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects
Identify And Prevent Memory Leaks In Managed Code
Hope it helps to start.
Not a book, but our team has used the ANTS Memory Profiler with pretty good success for tracking down managed memory leaks. Their support section and included help walks you through the process of tracking down different types of memory issues. This doesn't include specifics on the GC class itself, just how to track down common mistakes (event handler deregistration, static variables, etc.).
Also not a book, but decent article.
Memory Leak Detection in .NET
There is an excellent article by Rico Mariani: Tracking down managed memory leaks (how to find a GC leak). I used this technique often and is easy and efficient. And getting yourself familiar with a true debugger like Windbg is a bonus side benefit!
There is also the SciTech .NET Memory Profiler, our team has been using that successfully.
To complement the answers above, there are more recent videos on Channel9 with Maoni Stephens (Principal developer for the GC on the CLR team at Microsoft) that walk you through basics of GC, what developers should look out for, how they should troubleshoot, and some of the tools you can use. I found the explanation of how the GC works and the concept of generations and roots really useful.
Here is the first part of a 3 episode series :
http://channel9.msdn.com/Shows/Defrag-Tools/Defrag-Tools-33-CLR-GC-Part-1

C# Memory leak, tracking techinques and tools

The app I am writing is suffering quite dramatically from a memory leak. Pretty much the entire object model is staying in memory when a user closes down a loaded project. The way I know this is because closing a project in my app barely effects the memory usage in the task manager and then opening a new project almost makes it double each time. I downloaded jetBrain's dotTrace Memory 3.5 but there is little (none) instructions for use. I kinda figured out how to use it and it shows that the whole object model is still in memory when i take a snapshot after a project has been closed down. Trawling through my projectClose code I can see no reason for this. Does anyone know of anything in particular that normally causes memory leaks in C# or of any tools or techniques for tracking down the problem. Its all well and good having an app that shows my entire object model is still loaded into memory but it doesnt show me what object or variable is storing it. Thanks in advance.
Firstly, investigate whether the leak could be due to registration of event handlers as this is one of the easiest ways to accidentally root your objects. For example, if you have a class 'Bob' that adds one of its methods 'OnSomeEvent' as a delegate to an event that is raised by a long-living component of your system (e.g. 'UserSettingsManager') then objects of class 'Bob' will not be collected as they are kept alive by virtue of being an event handler (i.e. event callbacks are not weak references).
As an alternative to the commercial tools, there is an extension to the Windows debugger called SoS (Son of Strike) that you can use to debug managed applications. However, it is not the faint-hearted as it is a low-level, command-line tool that requires a lot of up-front learning. It is very powerful, however, and does not struggle so much with larger processes (in terms of heap consumption) as the commercial tools do.
In terms of the commercial profilers, I've had good experiences with Redgate's ANTS Memory Profiler (but I have had colleagues who hate it) so it may be worth trialing that.
Probably the most common cause of managed memory leaks is unsubscribed event handlers.
There are a number of useful tools for tracking errors like this. Personally I like ANTS Memory Profiler and WinDbg/SOS. You want to find out what is rooting the object graphs. With WinDbg/SOS there's a !gcroot command, that will tell you the roots of any given object.
Check Tess' blog for guides on how to troubleshoot memory problems using WinDbg/SOS.
try these:
http://blogs.msdn.com/b/tess/archive/2010/01/14/debugging-native-memory-leaks-with-debug-diag-1-1.aspx
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=28bd5941-c458-46f1-b24d-f60151d875a3&displaylang=en

Has anyone written or knows of a custom memory manager written in C#?

We have certain application written in C# and we would like it to stay this way. The application manipulates many small and short lived chunks of dynamic memory. It also appears to be sensitive to GC interruptions.
We think that one way to reduce GC is to allocate 100K chunks and then allocate memory from them using a custom memory manager. Has anyone encountered custom memory manager implementations in C#?
Perhaps you should consider using some sort of pooling architecture, where you preallocate a number of items up front then lease them from the pool. This keeps the memory requirements nicely pinned. There are a few implementations on MSDN that might serve as reference:
http://msdn2.microsoft.com/en-us/library/bb517542.aspx
http://msdn.microsoft.com/en-us/library/system.net.sockets.socketasynceventargs.socketasynceventargs.aspx
...or I can offer my generic implementation if required.
Memory management of all types that descend from System.Object is performed by the garbage collector (with the exception of structures/primitives stored on the stack). In Microsoft's implementation of the CLR, the garbage collector cannot be replaced.
You can allocate some primitives on the heap manually inside of an unsafe block and then access them via pointers, but it's not recommended.
Likely, you should profile and migrate classes to structures accordingly.
The obvious option is using Marshal.AllocHGlobal and Marshal.FreeHGlobal. I also have a copy of the DougLeaAllocator (dlmalloc) written and battle-tested in C#. If you want, I can get that out to you. Either way will require careful, consistent usage of IDisposable.
The only time items are collected in garbage collection is when there are no more references to the object.
You should make a static class or something to keep a lifetime reference to the object for the life of the application.
If you want to manage your own memory it is possible using unsafe in C#, but you would be better to choose a language that wasn't managed like C++.
Although I don't have experience with it, you can try to write C# unmanaged code.
Or maybe, you can tell GC to not collect your objects by calling
GC.KeepAlive(obj);

Strategies For Tracking Down Memory Leaks When You've Done Everything Wrong

My program, alas, has a memory leak somewhere, but I'll be damned if I know what it is.
Its job is to read in a bunch of ~2MB files, do some parsing and string replacement, then output them in various formats. Naturally, this means a lot of strings, and so doing memory tracing shows that I have a lot of strings, which is exactly what I'd expect. The structure of the program is a series of classes (each in their own thread, because I'm an idiot) that acts on an object that represents each file in memory. (Each object has an input queue that uses a lock on both ends. While this means I get to run this simple processing in parallel, it also means I have multiple 2MB objects sitting in memory.) Each object's structure is defined by a schema object.
My processing classes raise events when they've done their processing and pass a reference to the large object that holds all my strings to add it to the next processing object's queue. Replacing the event with a function call to add to the queue does not stop the leak. One of the output formats requires me to use an unmanaged object. Implementing Dispose() on the class does not stop the leak. I've replaced all the references to the schema object with an index name. No dice. I got no idea what's causing it, and no idea where to look. The memory trace doesn't help because all I see are a bunch of strings being created, and I don't see where the references are sticking in memory.
We're pretty much going to give up and roll back at this point, but I have a pathological need to know exactly how I messed this up. I know Stack Overflow can't exactly comb my code, but what strategies can you suggest for tracking this leak down? I'm probably going to do this in my own time, so any approach is viable.
One technique I would try is to systematically reduce the amount of code you need to demonstrate the problem without making the problem go away. This is informally known as "divide and conquer" and is a powerful debugging technique. Once you have a small example that demonstrates the same problem, it will be much easier for you to understand. Perhaps the memory problem will become clearer at that point.
There is only one person who can help you. That person's name is Tess Ferrandez. (hushed silence)
But seriously. read her blog (the first article is pretty pertinent). Seeing how she debugs this stuff will give you a lot of deep insight into knowing what's going on with your problem.
I like the CLR Profiler from Microsoft. It provides some great tools for visualizing the managed heap and tracking down leaks.
I use the dotTrace profiler for tracking down memory leaks. It's a lot more deterministic than methodological trial and error and turns up results a lot faster.
For any actions that the system performs, I take a snapshot then run a few iterations of the function, then take another snapshot. Comparing the two will show you all the objects that were created in between but were not freed. You can then see the stack frame at the point of their creation, and therefore work out what instances are not being freed.
Get this: http://www.red-gate.com/Products/ants_profiler/index.htm
The memory and performance profiling are awesome. Being able to actually see proper numbers instead of guessing makes optimisation pretty fast. I've used it quite a bit at work for reducing the memory footprint of our main app.
Add code to the constructor of the
unamanaged object to log when it's
onstructed, and sort a unique ID.
Use that unique ID when the object
is destroyed again, and you can at
least tell which ones are going
astray.
Grep the code for every place you
construct a new object; follow that
code path to see if you have a
matching destroy.
Add chaining pointers to the
constructed objects, so you have a
link to the object constructed
before and after the current one. Then you can sweep through them later.
Add reference counters.
Is there a "debug malloc" available?
The managed debugging add in SoS (Son of Strike) is immensely poweful for tracking down managed memory 'leaks' since they are, by definition discoverable from the gc roots.
It will work in WinDbg or Visual studio (though it is in many respects easier to use in WinDbg)
It is not at all easy to get to grips with. Here is a tutorial
I would second the recommendation to check out Tess Fernandez's blog too.
How do you know for a fact that you actually have a memory leak?
One other thing: You write that your processing classes are using events. If you have registered an event handler it will keep the object that owns the event alive - i.e. the GC cannot collect it. Make sure you de-register all event handlers if you want your objects to be garbage collected.
Be careful how you define "leak". "Uses more memory" or even "uses too much memory" is not the same as "memory leak". This is especially true in a garbage-collected environment. It may simply be that GC hasn't needed to collect the extra memory you're seeing used. Also be careful about the difference between virtual memory use and physical memory use.
Finally not all "memory leaks" are caused by "memory" sorts of issues. I was once told (not asked) to fix an urgent memory leak that was causing IIS to restart frequently. In fact, I did profiling and found I was using a lot of strings through the StringBuilder class. I implemented an object pool (from an MSDN article) for the StringBuilders, and memory usage went down substantially.
IIS still restarted just as frequently. This was because there was no memory leak. Instead, there was unmanaged code that claimed to be thread-safe but was not. Using it in a web service (multiple threads) caused it to write all over the C Runtime Library heap. Since nobody was looking for unmanaged exceptions, nobody saw this until I happened to do some profiling with AQtime from Automated QA. It happens to have an events window, that happened to display the cries of pain from the C Runtime Library.
Placed locks around the calls to the unmanaged code, and the "memory leak" went away.
If your unmanaged object really is the cause of the leak, you may want to have it call AddMemoryPressure when it allocates unmanaged memory and RemoveMemoryPressure in Finalize/Dispose/where ever it deallocates the unmanaged memory. This will give the GC a better handle on the situation, because it may not realize there's a need to schedule collection otherwise.
You mentioned that your using events. Are you removing the handlers from those events when your done with your object? I've found that 'loose' event handlers will cause a lot of memory leak problems if you add a bunch of handlers without removing them when your done.
The best memory profiling tool for .Net is this:
http://memprofiler.com
Also, while I'm here, the best performance profiler for .Net is this:
http://www.yourkit.com/dotnet/download/index.jsp
They are also great value for money, have low overhead and are easy to use. Anyone serious about .Net development should consider both of these a personal investment and purchase immediately. Both of them have a free trial.
I work on a real time game engine with over 700k lines of code written in C# and have spent hundreds of hours using both these tools. I have used the Sci Tech product since 2002 and YourKit! for the last three years. Although I've tried quite a few of the others I have always returned to these.
IMHO, they are both absolutely brilliant.
Similar to Charlie Martin, you can do something like this:
static unigned __int64 _foo_id = 0;
foo::foo()
{
++_foo_id;
if (_foo_id == MAGIC_BAD_ALLOC_ID)
DebugBreak();
std::werr << L"foo::foo # " << _foo_id << std::endl;
}
foo::~foo()
{
--_foo_id;
std::werr << L"foo::~foo # " << _foo_id << std::endl;
}
If you can recreate it, even once or twice with the same allocation id, this will let you look at what is happening right then and there (obviously TLS/threading has to be handled as well, if needed, but I left it out for clarity).

Categories

Resources