Tracking .NET-Objects in Memory - c#

I am writing an editor in C#/.NET using AvalonDock.
If i close a document, the memory-consumption of my program doesn't decrease. Even if I call the garbage collector manually. So i assume that there is still a reference of the document somewhere.
The software is huge and the document is a very central component, so it's not easy to find every reference to it.
Does the Visual Studio 2010 debugger have a functionality to search for objects of a certain class in memory or something?
Alternatively, what would you do, if faced with such a problem?

You need to use a memory profiler to find out what objects are in memory and what holds a reference to them.
There are several different options - commercial and free.

You can do what you want using free tools.
The basic steps are as follows:
Run Your Application
Attach windbg to its process
Load the "sos" helper module (.loadby sos mscorwks)
Dump the heap (!DumpHeap -stat)
Find the type you're interested in and see if it's actually the thing using memory
Dump the heap for your particular type (!DumpHeap -type MyNameSpace.MyType)
Find the memory address of an object you think should be disposed, and see if it is "rooted" somewhere. (!gcroot "whatever the address was")
I've personally used this technique to great effect when tracking down memory leaks in graphics-intensive c# programs.
I learned this from Rico Mariani of Microsoft. Here is a blog entry that describes it in detail.
* http://blogs.msdn.com/b/ricom/archive/2004/12/10/279612.aspx

Remember that even when .net cleans itself up, windows may not decide to actually release the memory. Often it only does so when another application actually needs memory. So, use a memory profiler :)

Related

Tracking Down a .NET Windows Service Memory Leak

Before installing my windows service in production, I was looking for reliable tests that I can perform to make sure my code doesn't contain memory leaks.
However, All what I can find on the net was using task manager to look at used memory or some paid memory profiler tools.
From my understanding, looking at the task manager is not really helpful and cannot confirm the memory leakage (in case, there is).
How to confirm whether there is a memory leak or not?
Is there any free tools to find the source of memory leaks?
Note: I'm using .Net Framework 4.6 and Visual Studio 2015 Community
Well you can use task manager.
GC apps can leak memory, and it will show there.
But...
Free tool - ".Net CLR profiler"
There is a free tool, and it's from Microsoft, and it's awesome. This is a must-use for all programs that leak references. Search MS' site.
Leaking references means you forget to set object references to null, or they never leave scope, and this is almost as likely to occur in Garbage collected languages as not - lists building up and not clearing, event handlers pointing to delegates, etc.
It's the GC equivalent of memory leaks and has the same result. This program tells you what references are taking up tons of memory - and you will know if it's supposed to be that way or not, and if not, you can go find them and fix the problem!
It even has a cool visualization of what objects allocate what memory (so you can track down mistakes). I believe there are youtubes of this if you need an explanation.
Wikipedia page with download links...
NOTE: You will likely have to run your app not as a service to use this. It starts first and then runs your app. You can do this with TopShelf or by just putting the guts in a dll that runs from an EXE that implments the service integrations (service host pattern).
Although managed code implies no direct memory management, you still have to manage your instances. Those instances 'claim' memory. And it is all about the usage of these instances, keeping them alive when you don't expect them to be.
Just one of many examples: wrong usage of disposable classes can result in a lot of instances claiming memory. For a windows service, a slow but steady increase of instances can eventually result in to much memory usage.
Yes, there is a tool to analyze memory leaks. It just isn't free. However you might be able to identify your problem within the 7 day trial.
I would suggest to take a loot at the .NET Memory Profiler.
It is great to analyze memory leaks during development. It uses the concept of snapshots to compare new instances, disposed instances etc. This is a great help to understand how your service uses its memory. You can then dig deeper into why new instances get created or are kept alive.
Yes, you can test to confirm whether memory leaks are introduced.
However, just out-of-the box this will not be very useful. This is because no one can anticipate what will happen during runtime. The tool can analyze your app for common issues, but this is not guaranteed.
However, you can use this tool to integrate memory consumption into your unit test framework like NUnit or MSTest.
Of course a memory profiler is the first kind of tool to try, but it will only tell you whether your instances keep increasing. You still want to know whether it is normal that they are increasing. Also, once you have established that some instances keep increasing for no good reason, (meaning, you have a leak,) you will want to know precisely which call trees lead to their allocation, so that you can troubleshoot the code that allocates them and fix it so that it does eventually release them.
Here is some of the knowledge I have collected over the years in dealing with such issues:
Test your service as a regular executable as much as possible. Trying to test the service as an actual service just makes things too complicated.
Get in the habit of explicitly undoing everything that you do at the end of the scope of that thing which you are doing. For example, if you register an observer to the event of some observee, there should should always be some point in time (the disposal of the observer or the observee?) that you de-register it. In theory, garbage collection should take care of that by collecting the entire graph of interconnected observers and observees, but in practice, if you don't kick the habit of forgetting to undo things that you do, you get memory leaks.
Use IDisposable as much as possible, and make your destructors report if someone forgot to invoke Dispose(). More about this method here: Mandatory disposal vs. the "Dispose-disposing" abomination Disclosure: I am the author of that article.
Have regular checkpoints in your program where you release everything that should be releasable (as if the program is performing an orderly shutdown in order to terminate) and then force a garbage collection to see whether you have any leaks.
If instances of some class appear to be leaking, use the following trick to discover the precise calling tree that caused their allocation: within the constructor of that class, allocate an exception object without throwing it, obtain the stack trace of the exception, and store it. If you discover later that this object has been leaked, you have the necessary stack trace. Just don't do this with too many objects, because allocating an exception and obtaining the stack trace from it is ridiculously slow, only Microsoft knows why.
You could try the free Memoscope memory profiler
https://github.com/fremag/MemoScope.Net
I do not agree that you can trust the Task Manager to check if you have a memory leak or not. The problem with a garbage collector is that it can decide based on heuristics to keep the memory after a memory spike and do not return it to the OS. You might have a 2 GB Commit size but 90% of them can be free.
You should use VMMAP to check during the tests what type of memory your process contains. You do not only have the managed heap, but also unmanaged heap, private bytes, stacks (thread leaks), shared files and much more which need to be tracked.
VMMap has also command line interface which makes it possible to create snapshots at regular intervals which you can examine later. If you have a memory growth you can find out which type of memory is leaked which needs depending on the leak type different debugging tooling approaches.
I would not say that the Garbage collector is infallible. There are times when it fails unknowingly and they are not so straight forward. Memory streams are a common cause of memory leaks. You can open them in one context and they may never even get closed, even though the usage is wrapped in a using statement (the definition of a disposable object that should be cleaned up immediately after its usage falls out of scope). If you are experiencing crashes due to running out of memory, Windows does create dump files that you can sift through.
enter link description here
This is by no means fun or easy and is quite tedious but it tends to be your best bet.
Common areas that are easy to create memory leaks are anything that is using the System.Drawing dll, memory streams, and if you are doing some serious multi-threading.
If you use Entity Framework and a DI pattern, perhaps using Castle Windsor, you can easily get memory leaks.
The main thing to do is use the using( ){ } statement where-ever you can to automatically mark objects as disposed.
Also, you want to turn off automatic tracking on Entity Framework where you are only reading and not writing. Best to isolate your writes, use a using() {} at this point, get a dbContext (with tracking on), write your data.
If you want to investigate what is on the heap. The best tool I've used is RedGate ANTS http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/solving-memory-problems/getting-started not cheap but it works.
However, by using the using() {} pattern where-ever you can (don't make a static or singleton DbContext and never have one context in a massive loop of updates, dispose of them as often as you can!) then you find memory isn't often an issue.
Hope this helps.
Unless you're dealing with unmanaged code, i would be so bold to say you don't have to worry about memory leaks. Any unreferenced object in managed code will be removed by the garbage collector, and the possibility in finding a memory leak within the .net framework i would say you should be considered very lucky (well, unlucky). You don't have to worry about memory leak.
However, you can still encounter ever-growing memory usage, if references to objects are never released. For example, say you keep an internal log structure, and you just keep adding entries to a log list. Then every entry still have references from the log list and therefore will never be collected.
From my experience, you can definitely use the task manager as an indicator whether your system has growing issues; if the memory usage steadily keep rising, you know you have an issue. If it grows to a point but eventually converges to a certain size, it indicates it has reached its operating threshold.
If you want a more detailed view of managed memory usage, you can download the process explorer here, developed by Microsoft. It is still quite blunt, but it gives a somewhat better statistical view than task manager.

How to detect where a Memory Leak is?

I have a large website that seems to be sucking up all the memory that is being allocated. There is nothing else on the server beside this site. Within a week it eats away the 2 gigs and requires a restart. Currently this is server 2008 32 bit using IIS 7. We are reinstalling to use 64bit and add more memory. It would be nice to be able to track down where the leaks are occurring.
So what is the best practice to tracking memory leaks?
Memory leaks in .NET are not that common, but when they happen it is most commonly due to unattached event handlers. Make sure you detach handlers, before the listeners go out of scope.
Another option is if you forget to call Dispose() on IDisposable resources. This may prevent cleanup of unmanaged resources (which are not handled by GC).
And yet another possible reason is a deadlocked finalizer. That will prevent all remaining objects in the finalizer queue from being collected.
I use WinDbg + Sos to track down leaks. The steps are as follows
Dump the heap and look for suspects
Use !gcroot to find out what is keeping the suspects alive
Repeat as necessary
Be aware that large memory usage may also be due to heap fragmentation. The regular heaps are compacted, but pinned objects can cause fragmentation. Also, the LOH is not compacted so fragmentation is not uncommon for LOH.
Excellent tutorials on WinDbg + sos here: http://blogs.msdn.com/tess/
Run a profiler on your code.
Here are two good options:
RedGate's memory profiler
Jetbrains dotTrace
I believe both products have a free trial.
Run, don't walk, over to Tess
Ferrandez's blog, If broken it is,
fix it you should, which has well
scripted labs dedicated to learning
how to diagnose and debug crash, hang
and memory issues with .NET code. She
has some of the best material I've
found to date to help get you started.
Commercial memory profilers such as ANTS and SciTech are excellent resources that will show what objects are in the heap, and how they are rooted. Most commercial memory profilers have the ability to load a memory 'snap' of a process (say from your production environment).
You can capture a memory 'snap' (see Snap v. Dump) using adplus.vbs or DebugDiag. Adplus is available as part of the Debugging Tools for Windows. DebugDiag will also have some rudimentary analysis (but seems to be more reliable on unmanaged code) automagically.
Monitor the Application
For an idea on what to monitor, see Improving .NET Performance and Scalability, specifically Chapter 15.
As to how to monitor, there are commercial tools available for that as well, however, every Windows machine also comes with Perfmon.exe, which can be used to record relevant performance counters.
Test the Application
For an idea on how to perform load, or stress, tests, check out the Patterns and Practices Performance Testing Guidance for Web Applications.
Debug the Application
Once you've identified you've got a problem (monitoring) and your able to reproduce the problem (testing) you can get down to debugging the problem. See the links for Tess - that information will carry you a long way.
Then rinse and repeat! :)
Good luck!
Z
In performance monitor, add counters for Process/Private Bytes and .NET CLR Memory/# Bytes in All Heaps. Private bytes is all memory and CLR memory is just managed. So if the CLR memory remains fairly even but the private bytes continues to grow over time, this means that the leak is in unmanaged resource. That usually means that you are not disposing of native resources properly. A good thing to look at is stuff like COM or IO (streams and files). Make sure all of that stuff gets disposed when you are done with it.
You can try using profilers such as dotTrace -- set it into a memory trace and run your application.
This should give you clues in which assemblies and areas of the application that eat up too much memory on the get go.
This is probably prevention rather then detection, but at the c# code level, you should check that any classes that use large resources such as images and other files are correctly implementing the dispose pattern. If needed you may also need to override the finalizer.
MSDN has good guidance on this subject.
If you have any classes in your application that you know make use of large resources, these are the first places to look for memory issues.
I've found that the EQATEC Profiler is pretty good, plus it's free!
Check out the Memory and Memory Leak labs on this blog post:
.NET Debugging Demos
They may be of some help. Basically, you can use WinDBG to analyze a memory dump and help determine what is eating up all of your memory.
We used a similar approach to determine that Regex was chewing up all of our memory, but only when the product was run on 64-bit machines. The learning curve is kind of steep, but WinDBG is a very powerful tool.
This new article of mine maybe useful: How to detect and avoid memory and resources leaks in .NET applications
Do you do any Office interop? If so, make sure you clean up your application objects. That's one possible culprit.
Another is global objects, such as anything that's static.
Do you have lots of dynamic pages on your site?
You can also try IBM's Purify
I suggest you try with a small set of dynamic pages disabling all others for the meantime. I hate to say this but it's very much possible that IIS 7 may also have leaks.
Look at this article on detecting .NET application memory leaks and related articles mentioned at the bottom of the page and hopefully you will find a solution or at least an idea to resolve it.
Thanks

COM C# Memory leak Tracing

Is there a way to find out the memory usage of each dll within a c# application using com dll's? Or what would you say is the best way to find out why memory grows exponentially when using a com object (IE. Whether the COM object has a memory leak, or whether some special freeing up of objects passed to managed code has to occur(and/or how to do that)).
Are you releasing the COM object after usage(Marshal.ReleaseComObject)?
What type of parameters are you passing in/out of the calls?
If you don't have the COM object source code and want to determine why its 'leaking', Run the COM object outa proc, attach WinDBG to the process and set breakpoints on memory allocation APIs(HeapAlloc,etc...). Look at the call stack and allocation patterns. Sure you can use profilers on the managed side but if you want to know what is going on you are going to have to get your hands dirty...
A Microsoft support engineer has a fabulous blog that walks through lots of cases like this. She goes over all the tools she uses. I found it extremely helpful to read through all of her posts when I was debugging this kind of stuff a few years ago.
Edit: Apparently, she has added a series of labs that explain how to setup your environment and diagnose different problems. You may want to start here.
dotTrace rocks: http://www.jetbrains.com/profiler/
Keep in mind that all COM objects in .NET are basically MarshalByRefObject-derived classes at heart, so you should be able to look for memory consumption by such objects as one potential filter.
First thing I'd want to do is be absolutely certain that I'm not leaking references anywhere, then go into the smallest steps that will reproduce the steps (a good profiler is essential, I happen to use and recommend RedGate's ANTS Profiler) -- it can be done, and it is worth sending example code that reproduces the issue to the vendor of the COM object so they can resolve it (There is actually a hotfix for Crystal Reports as a result of a memory leak in it which I found :)

Memory Leaks in C# WPF

I could use some advice on tracking down the cause of memory leaks in C#. I understand what is a memory leak and I get why they occur in C# but I'm wondering what tools/strategies have you used in the past to resolve them?
I am using .NET Memory Profiler and I've found that one of my huge main objects is staying in memory after I close the window it manages but I'm not sure what to do to severe all links to it.
If I'm not being clear enough just post an answer with a question and I'll edit my question in response. Thanks!
Break into the debugger and then type this into the Immediate window:
.load C:\Windows\Microsoft.NET\Framework\v2.0.50727\sos.dll
The path to sos.dll varies. The way to find out the correct path is to look for mscorwks.dll in the Modules pane. Wherever that is loaded from is the correct path for sos.dll.
Then type this:
System.GC.Collect()
That will ensure anything not reachable is collected. Then type this:
!DumpHeap -type <some-type-name>
This will show you a table of all existing instances, with addresses. You can find out what is keeping an instance alive like this:
!gcroot <some-address>
.NET Memory Profiler is an excellent tool, and one that I use frequently to diagnose memory leaks in WPF applications.
As I'm sure you're aware, a good way to use it is to take a snapshot before using a particular feature, then take a second snapshot after using it, closing the window, etc. When comparing the two snapshots, you can see how many objects of a certain type are being allocated but not freed: this is a leak.
After double-clicking on a type, the profiler will show you the shortest root paths keeping objects of that type alive. There are many different ways that .NET objects can leak in WPF, so posting the root path that you are seeing should help identify the ultimate cause. In general, however, try to understand why those objects are holding onto your object, and see if there's some way you can detach your event handlers, bindings, etc. when the window is closed.
I recently posted a blog entry about a particular memory leak that can be caused by certain bindings; for that specific types of leak, the code there is useful for finding the Binding that's at fault.

What strategies and tools are useful for finding memory leaks in .NET?

I wrote C++ for 10 years. I encountered memory problems, but they could be fixed with a reasonable amount of effort.
For the last couple of years I've been writing C#. I find I still get lots of memory problems. They're difficult to diagnose and fix due to the non-determinancy, and because the C# philosophy is that you shouldn't have to worry about such things when you very definitely do.
One particular problem I find is that I have to explicitly dispose and cleanup everything in code. If I don't, then the memory profilers don't really help because there is so much chaff floating about you can't find a leak within all the data they're trying to show you. I wonder if I've got the wrong idea, or if the tool I've got isn't the best.
What kind of strategies and tools are useful for tackling memory leaks in .NET?
I use Scitech's MemProfiler when I suspect a memory leak.
So far, I have found it to be very reliable and powerful. It has saved my bacon on at least one occasion.
The GC works very well in .NET IMO, but just like any other language or platform, if you write bad code, bad things happen.
Just for the forgetting-to-dispose problem, try the solution described in this blog post. Here's the essence:
public void Dispose ()
{
// Dispose logic here ...
// It's a bad error if someone forgets to call Dispose,
// so in Debug builds, we put a finalizer in to detect
// the error. If Dispose is called, we suppress the
// finalizer.
#if DEBUG
GC.SuppressFinalize(this);
#endif
}
#if DEBUG
~TimedLock()
{
// If this finalizer runs, someone somewhere failed to
// call Dispose, which means we've failed to leave
// a monitor!
System.Diagnostics.Debug.Fail("Undisposed lock");
}
#endif
We've used Ants Profiler Pro by Red Gate software in our project. It works really well for all .NET language-based applications.
We found that the .NET Garbage Collector is very "safe" in its cleaning up of in-memory objects (as it should be). It would keep objects around just because we might be using it sometime in the future. This meant we needed to be more careful about the number of objects that we inflated in memory. In the end, we converted all of our data objects over to an "inflate on-demand" (just before a field is requested) in order to reduce memory overhead and increase performance.
EDIT: Here's a further explanation of what I mean by "inflate on demand." In our object model of our database we use Properties of a parent object to expose the child object(s). For example if we had some record that referenced some other "detail" or "lookup" record on a one-to-one basis we would structure it like this:
class ParentObject
Private mRelatedObject as New CRelatedObject
public Readonly property RelatedObject() as CRelatedObject
get
mRelatedObject.getWithID(RelatedObjectID)
return mRelatedObject
end get
end property
End class
We found that the above system created some real memory and performance problems when there were a lot of records in memory. So we switched over to a system where objects were inflated only when they were requested, and database calls were done only when necessary:
class ParentObject
Private mRelatedObject as CRelatedObject
Public ReadOnly Property RelatedObject() as CRelatedObject
Get
If mRelatedObject is Nothing
mRelatedObject = New CRelatedObject
End If
If mRelatedObject.isEmptyObject
mRelatedObject.getWithID(RelatedObjectID)
End If
return mRelatedObject
end get
end Property
end class
This turned out to be much more efficient because objects were kept out of memory until they were needed (the Get method was accessed). It provided a very large performance boost in limiting database hits and a huge gain on memory space.
You still need to worry about memory when you are writing managed code unless your application is trivial. I will suggest two things: first, read CLR via C# because it will help you understand memory management in .NET. Second, learn to use a tool like CLRProfiler (Microsoft). This can give you an idea of what is causing your memory leak (e.g. you can take a look at your large object heap fragmentation)
Are you using unmanaged code? If you are not using unmanaged code, according to Microsoft, memory leaks in the traditional sense are not possible.
Memory used by an application may not be released however, so an application's memory allocation may grow throughout the life of the application.
From How to identify memory leaks in the common language runtime at Microsoft.com
A memory leak can occur in a .NET
Framework application when you use
unmanaged code as part of the
application. This unmanaged code can
leak memory, and the .NET Framework
runtime cannot address that problem.
Additionally, a project may only
appear to have a memory leak. This
condition can occur if many large
objects (such as DataTable objects)
are declared and then added to a
collection (such as a DataSet). The
resources that these objects own may
never be released, and the resources
are left alive for the whole run of
the program. This appears to be a
leak, but actually it is just a
symptom of the way that memory is
being allocated in the program.
For dealing with this type of issue, you can implement IDisposable. If you want to see some of the strategies for dealing with memory management, I would suggest searching for IDisposable, XNA, memory management as game developers need to have more predictable garbage collection and so must force the GC to do its thing.
One common mistake is to not remove event handlers that subscribe to an object. An event handler subscription will prevent an object from being recycled. Also, take a look at the using statement which allows you to create a limited scope for a resource's lifetime.
This blog has some really wonderful walkthroughs using windbg and other tools to track down memory leaks of all types. Excellent reading to develop your skills.
I just had a memory leak in a windows service, that I fixed.
First, I tried MemProfiler. I found it really hard to use and not at all user friendly.
Then, I used JustTrace which is easier to use and gives you more details about the objects that are not disposed correctly.
It allowed me to solve the memory leak really easily.
If the leaks you are observing are due to a runaway cache implementation, this is a scenario where you might want to consider the use of WeakReference. This could help to ensure that memory is released when necessary.
However, IMHO it would be better to consider a bespoke solution - only you really know how long you need to keep the objects around, so designing appropriate housekeeping code for your situation is usually the best approach.
I prefer dotmemory from Jetbrains
Big guns - Debugging Tools for Windows
This is an amazing collection of tools. You can analyze both managed and unmanaged heaps with it and you can do it offline. This was very handy for debugging one of our ASP.NET applications that kept recycling due to memory overuse. I only had to create a full memory dump of living process running on production server, all analysis was done offline in WinDbg. (It turned out some developer was overusing in-memory Session storage.)
"If broken it is..." blog has very useful articles on the subject.
After one of my fixes for managed application I had the same thing, like how to verify that my application will not have the same memory leak after my next change, so I've wrote something like Object Release Verification framework, please take a look on the NuGet package ObjectReleaseVerification. You can find a sample here https://github.com/outcoldman/OutcoldSolutions-ObjectReleaseVerification-Sample, and information about this sample http://outcoldman.com/en/blog/show/322
The best thing to keep in mind is to keep track of the references to your objects. It is very easy to end up with hanging references to objects that you don't care about anymore.
If you are not going to use something anymore, get rid of it.
Get used to using a cache provider with sliding expirations, so that if something isn't referenced for a desired time window it is dereferenced and cleaned up. But if it is being accessed a lot it will say in memory.
One of the best tools is using the Debugging Tools for Windows, and taking a memory dump of the process using adplus, then use windbg and the sos plugin to analyze the process memory, threads, and call stacks.
You can use this method for identifying problems on servers too, after installing the tools, share the directory, then connect to the share from the server using (net use) and either take a crash or hang dump of the process.
Then analyze offline.
From Visual Studio 2015 consider to use out of the box Memory Usage diagnostic tool to collect and analyze memory usage data.
The Memory Usage tool lets you take one or more snapshots of the managed and native memory heap to help understand the memory usage impact of object types.
one of the best tools I used its DotMemory.you can use this tool as an extension in VS.after run your app you can analyze every part of memory(by Object, NameSpace, etc) that your app use and take some snapshot of that, Compare it with other SnapShots.
DotMemory

Categories