My app was using 150mb of memory not to long ago, now it is at 286mb. It slowly rises so i must be forgetting to dispose something. This isnt much of a problem for me since i have 4gb but i want to send this to others who have only 1gb of ram. other then going through the code line by line how can i find objects that need to be disposed of or just generally large objects?
Extending both JP and Reed's answers.
I wanted to clear up a bit of confusion. If you are seeing significant increases in memory the issue is unlikely to be a problem with calling Dispose. Dispose is typically used to free up unmanaged resources like handles. These don't take up much memory but instead are more precious as resources.
Increases in memory are generally associated with large objects or collections being accessible from a managed object being rooted directly or indirectly via a stack object or a strong GC handle. This is the area you will likely want to focus your investigation on.
Check out the .NET Memory Profiler. There is a 15-day trial and it's well worth the license fee.
Easily identify memory leaks by
collecting and comparing snapshots of
.NET memory Snapshots include data
about the .NET instance allocations
and live instances at the time the
snapshot was collected. They provide a
lot of useful information and make it
easy to identify potential memory
leaks, especially when two snapshots
are compared.
heres a method i use:
http://www.codeproject.com/KB/dotnet/Memory_Leak_Detection.aspx
You can also use WinDbg and SOS. These have the advantage of being free and very, very thorough, if a bit tricky to get used to.
Here's a blog post describing the process.
Here are couple of tricks using the ANTS Memory Profiler to help find undisposed objects and fix the leaks.
The ANTS Memory profiler allows a filter to be set that show just
objects that contain a Dispose() method. Turn this on, and you'll be
given a list of live objects that have not been disposed.
While finding undisposed objects is useful, even more useful is
knowing why these objects are not being disposed. Finding where these
undisposed objects are created goes a long way to finding the
reason for the leak. If you are able to change the code of the leaking object, a
useful trick is to introduce a field to hold a stacktrace, and
populate this field at the time of object construction. Then because
the ANTS memory profiler allows you to inspect fields of objects,
you can simply read off the stacktrace as it was at the time the leaking objects were created. This will give you a strong clue as to who the
owner of the leaking objects should be, and how they should go about calling Dispose on the objects they are responsible for.
Code project currently has a link to an app specifically for finding undisposed objects.
http://www.codeproject.com/KB/dotnet/undisposed.aspx
Check out this link
Stephen Toub goes into great length to explain various techniques for doing this,
Following are some brief highlights from his article
By adding a finalizer for debugging purposes, you can introduce a way to find out when
a class was not properly disposed,if the finalizer is never invoked, you know that
disposed wasn't called
To get additional information about the instance, threadIds etc to aid in narrowing down
which instance didn't have it's disposed invoked, he creates a FinalizationDebgger class
which your disposable class would hold onto which wouldin turn call the Dispose of the
FinalizationDebugger class instance when it itself is disposed. If Dispose isn't called on
your class instance then when the Finalizer runs it will invoke the finalizer for
FinalizationDebgger instance where in you could assert or throw an exception to help debug
the problem,
Move all the tracking related code into a base class which your disposable class would
then inherit from, which makes the code much cleaner. This approach may or may not work
since your burn a base class and if you are inheriting from another base already.
In the last option everything is factored out into a static class that your instances
call into. The FinalizationDebugger becomes a static class that exposes three static
methods: Constructor, Dispose, and Finalizer. The idea is that you call these methods
from the appropriate place in your class(dispose/finalize/constructor).This is minimally
invasive into your code, as it typically involves adding only three lines of code. All
of these methods are marked with a ConditionalAttribute such that they'll only be called
by your class when you compile your class in DEBUG mode.
Stephen also explains the pros and cons of each of his approaches.
The solutions presents various options and you would need to evaluate each to figure out which one works best for your situation. A MUST read IMHO
Hope this helps.
Also try out ANTS Memory Profiler. There's a 14 day fully functional free trial, and I really like the UI.
Disclosure: They sponsor Herding Code right now, which is why I tried it out. But I'm really impressed with it - I profiled an application for 30 hours and got tons of useful information out of it. The UI is really helpful - it guides you through the process, and it looks dang purty.
alt text http://www.red-gate.com/products/ants_memory_profiler/images/object_retention_graph.gif
Related
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.
I need to dispose of an object so it can release everything it owns, but it doesn't implement the IDisposable so I can't use it in a using block. How can I make the garbage collector collect it?
You can force a collection with GC.Collect(). Be very careful using this, since a full collection can take some time. The best-practice is to just let the GC determine when the best time to collect is.
Does the object contain unmanaged resources but does not implement IDisposable? If so, it's a bug.
If it doesn't, it shouldn't matter if it gets released right away, the garbage collector should do the right thing.
If it "owns" anything other than memory, you need to fix the object to use IDisposable. If it's not an object you control this is something worth picking a different vendor over, because it speaks to the core of how well your vendor really understands .Net.
If it does just own memory, even a lot of it, all you have to do is make sure the object goes out of scope. Don't call GC.Collect() — it's one of those things that if you have to ask, you shouldn't do it.
You can't perform garbage collection on a single object. You could request a garbage collection by calling GC.Collect() but this will effect all objects subject to cleanup. It is also highly discouraged as it can have a negative effect on the performance of later collections.
Also, calling Dispose on an object does not clean up it's memory. It only allows the object to remove references to unmanaged resources. For example, calling Dispose on a StreamWriter closes the stream and releases the Windows file handle. The memory for the object on the managed heap does not get reclaimed until a subsequent garbage collection.
Chris Sells also discussed this on .NET Rocks. I think it was during his first appearance but the subject might have been revisited in later interviews.
http://www.dotnetrocks.com/default.aspx?showNum=10
This article by Francesco Balena is also a good reference:
When and How to Use Dispose and Finalize in C#
http://www.devx.com/dotnet/Article/33167/0/page/1
Garbage collection in .NET is non deterministic, meaning you can't really control when it happens. You can suggest, but that doesn't mean it will listen.
Tells us a little bit more about the object and why you want to do this. We can make some suggestions based off of that. Code always helps. And depending on the object, there might be a Close method or something similar. Maybe the useage is to call that. If there is no Close or Dispose type of method, you probably don't want to rely on that object, as you will probably get memory leaks if in fact it does contain resourses which will need to be released.
If the object goes out of scope and it have no external references it will be collected rather fast (likely on the next collection).
BEWARE: of f ra gm enta tion in many cases, GC.Collect() or some IDisposal is not very helpful, especially for large objects (LOH is for objects ~80kb+, performs no compaction and is subject to high levels of fragmentation for many common use cases) which will then lead to out of memory (OOM) issues even with potentially hundreds of MB free. As time marches on, things get bigger, though perhaps not this size (80 something kb) for LOH relegated objects, high degrees of parallelism exasperates this issue due simply due to more objects in less time (and likely varying in size) being instantiated/released.
Array’s are the usual suspects for this problem (it’s also often hard to identify due to non-specific exceptions and assertions from the runtime, something like “high % of large object heap fragmentation” would be swell), the prognosis for code suffering from this problem is to implement an aggressive re-use strategy.
A class in Systems.Collections.Concurrent.ObjectPool from the parallel extensions beta1 samples helps (unfortunately there is not a simple ubiquitous pattern which I have seen, like maybe some attached property/extension methods?), it is simple enough to drop in or re-implement for most projects, you assign a generator Func<> and use Get/Put helper methods to re-use your previous object’s and forgo usual garbage collection. It is usually sufficient to focus on array’s and not the individual array elements.
It would be nice if .NET 4 updated all of the .ToArray() methods everywhere to include .ToArray(T target).
Getting the hang of using SOS/windbg (.loadby sos mscoreei for CLRv4) to analyze this class of issue can help. Thinking about it, the current garbage collection system is more like garbage re-cycling (using the same physical memory again), ObjectPool is analogous to garbage re-using. If anybody remembers the 3 R’s, reducing your memory use is a good idea too, for performance sakes ;)
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
What are some tips I can use to avoid memory leaks in my applications? Are there any gotchas or pitfalls that I can look out for?
Call Dispose on IDisposable objects or use the using clause. That should take care of most of the leaks I can think of.
Watch that you remove any event handlers that you use. In .NET, they are the most common cause of leaked memory.
As mentioned by ocdecio be sure to call Dispose on Idisposable objects, and remember to remove event handlers when you're done with an object. When building classes that works with unmanaged resources, be sure to implement Idisposable, so the user will know that there are critical resources that'll need to be disposed of.
Also, even though garbage collections do quite a bit a work for you, you should get rid of references to objects that you're done with. Else they'll still have a root, and they won't be GC'ed.
Don't underestimate the helpfulness of tools in these situations. The .NET memory profilers are fairly mature and robust nowadays, and if you have a complicated application where an object that you think should be freed is still held as a reference by something else the ability to pinpoint that reference is invaluable.
I've just finished hunting down a memory leak where a WPF tab page hosted a Windows Form control (since these tabs held a lot of data and you could open and close them at will simply waiting until the GC cleared the memory on close was not an option). I used the YourKit profiler to take a snapshot of the memory before the tab was opened, opened a tab, closed it again and took another snapshot. Inside the profiler you could visually compare the two snapshots and see what objects had survived the process and follow their references back to the GC root. I have no experience with other profilers, but I know there are a few out there if YourKit doesn't fulfil your needs.
Edited to add:
Okay, this isn't avoiding memory leaks, it's fixing them. But I'll leave it here since I think it is useful information and I don't think that enough .NET developers know about these tools.
I know some people are going to advise garbage collection as the solution. But there are lots of cases where garbage collection doesn't give you the results that you expect. It is easy to end up holding on to a stray reference which prevents whole chains of memory from being freed. Read about how this torpedoed a DARPA Grand Challenge entry. You can argue these aren't memory leaks but if the program expects that memory to be freed it is still a problem. Just like in C programming, after a couple of months you get the hang of how to make sure you don't leave unwanted references behind.
Memory leaks are bugs, so in general - the question could be answered the same as "how to code without bugs"? In the long run - it is not possible to have no bugs, but you can limit the chance for having those in the released code.
Start with caring about developed code quality and following the guidelines mentioned by others.
Simplicity is golden - the more simple the code - the less a chance for bugs or leaks
Be careful when using unmanaged resources - Windows Handles, DB connections, GDI objects, etc.
Use using for IDisposables
Implement IDisposable for classes that carry unmanaged resources
Make sure to remove any references to unused objects - including the tricky event handlers
On top of these - implement tests to see if the memory leaks - unit, concurrency, stress and load tests could help here most. See if memory leaks by checking metrics (perf counters). You could also log object creations and destructions and analyze the logs at the end of a test.
I've ran into issues where an object (Ping) implemented Dispose() twice, by implementing the IDisposable interface and inheriting it at the same time. The inherited method did nothing, and as a result you had to cast the object to IDisposable when calling Dispose() or it would leak memory. Here's a post I wrote a few years ago with more detail.
Wrap anything which is disposable in a using construct.
Avoid COM objects.
Check to see that all event hanlders are being removed properly.
Check to see that all data bindings are being removed properly.
Keep it simple
If your application logic is getting needlessly complex, you might start ending up with memory leaks. If you keep your classes small and follow general coding practices you probably won't run into any memory leaks with managed code. It is possible, but not as likely as it use to be.
If you suspect a memory leak, use a profiler to see if any objects are being kept around longer than needed.
The last time I ran into a serious memory leak was .NET 1.1, it turned out there was a bug in the framework.
Having a basic understanding of how the garbage collector works will help you avoid abusing memory. For example, if you are keeping a reference to an object you no longer need, the gc won't be able to collect it.
Along the same lines, if you're storing data the the user enters, or data that is added over time, you should consider some kind of limitations so that your memory usage doesn't grow indefinitely.
Most memory leaks that I have encountered in .NET has been related to using COM objects and not releasing them properly. As soon as I see a reference to a COM object, I think "memory leak".
The most common case of memory not being destroyed by the GC is when you have event handlers that did not get unhooked properly. You can unhook in Dispose() if you want.
I describe the problem more in detail, and I have a way to write tests to determine if you leak the object here.
As others have said call Dispose() (or use a using statement), but additionally consider whether classes use resources and if so implement IDisposeable. This is most often the problem in my code is that I have a class with member that doesn't get cleaned up till a GC.
It's managed code, that c#, so you have to try hard to leak memory :P
Try google:
http://www.google.com/search?hl=en&client=firefox-a&rls=org.mozilla%3Aen-US%3Aofficial&hs=Mbp&q=c%23+memory+leaks&btnG=Search
Types which implement a finalizer may leak, if any one finalizer blocks for some reason. I have seen finalizers block due to locking and thread apartment issues.
As instances of types with finalizers are not collected until their respective finalizers have run a single blocking finalizer will block any other finalizable objects pending collection.
First, let me bring share my strict understanding of a memory leak. My definition of a memory leak is when you have memory you have allocated and no longer a reference to it, so it is not possible to free that memory. Having said that, it is impossible to have a memory leak in .net objects (instances of CTS types that live in the managed heap, I mean). Unreferenced memory is precisely what the GC looks for to free.
Having said that, one can have a more lax understanding of what a memory leak is. If you consider a memory leak to be a uncontrolled growth of the memory being used, well, that is very easy. Just make a big misuse of static variables, mostly ones that reference huge lists. If you keep those objects referenced, the GC will never clean them, promoting them to higher generations and making them even harder to collect. Even though this is not a memory leak in the strict sense, in the end of the day it can lead to similar symptoms. A good way to try to detect this kind of "leak" is to use the CLR Profiler.
Another source of "leaks" is through improper use of event handlers as previously stated. Every time that object A registers one of its instance methods with an event at object B, object B ends keeping an indirect reference to object A, which means that while B is alive, A will be kept alive. Please note however, that there is no circularity here. As soon as neither B or A have any root reference, no matter how many cross references they have, they will eventually be collected.
Finally, one can actually induce a memory leak in .net, but never (at least theoretically) when talking about managed memory, as the GC does an excellent job in clearing that. If any of your objects maintains a reference to unmanaged memory, for instance through interop, then that memory needs to be explicitly cleaned. Failing to do so can lead to a memory leak, indeed. Even though I've never experienced such a scenario, at least in theory this can happen. As previously stated, objects that hold such references ought to implement IDiposable in order to clear that memory and their usage should guarantee Dispose is invoked for that purpose, mainly through the usage of the using clause. Notice that Dispose will not free the object's memory, but will only ask the object to release any unmanaged memory it is referring to.
One special kind of unmanaged memory is the one needed by COM objects used in interop scenarios. These objects are accessed through Runtime Callable Wrappers, RCWs for friends, but have no Dispose. "Using" will not work. The way to release the underlying COM objects is through the static method:
System.Runtime.InteropServices.Marshal.ReleaseComObject(object);
Since "using" is only syntax sugar to call IDisposable.Dispose() in a finally block, it is not usable with RCWs, hence don't forget to place the call in ReleaseComObject(object) in a finally block yourself so you ensure it is really called.
Use "using" keyword to automatically call Dispose() method of IDisposable object.
For any COM interop you have to manually release all resources.
You may find my new article useful: How to detect and avoid memory and resources leaks in .NET applications
I'm learning C#. From what I know, you have to set things up correctly to have the garbage collector actually delete everything as it should be. I'm looking for wisdom learned over the years from you, the intelligent.
I'm coming from a C++ background and am VERY used to code-smells and development patterns. I want to learn what code-smells are like in C#. Give me advice!
What are the best ways to get things deleted?
How can you figure out when you have "memory leaks"?
Edit: I am trying to develop a punch-list of "stuff to always do for memory management"
Thanks, so much.
C#, the .NET Framework uses Managed Memory and everything (but allocated unmanaged resources) is garbage collected.
It is safe to assume that managed types are always garbage collected. That includes arrays, classes and structures. Feel free to do int[] stuff = new int[32]; and forget about it.
If you open a file, database connection, or any other unmanaged resource in a class, implement the IDisposable interface and in your Dispose method de-allocate the unmanaged resource.
Any class which implements IDisposable should be explicitly closed, or used in a (I think cool) Using block like;
using (StreamReader reader = new StreamReader("myfile.txt"))
{
... your code here
}
Here .NET will dispose reader when out of the { } scope.
The first thing with GC is that it is non-deterministic; if you want a resource cleaned up promptly, implement IDisposable and use using; that doesn't collect the managed memory, but can help a lot with unmanaged resources and onward chains.
In particular, things to watch out for:
lots of pinning (places a lot of restrictions on what the GC can do)
lots of finalizers (you don't usually need them; slows down GC)
static events - easy way to keep a lot of large object graphs alive ;-p
events on an inexpensive long-life object, that can see an expensive object that should have been cleaned up
"captured variables" accidentally keeping graphs alive
For investigating memory leaks... "SOS" is one of the easiest routes; you can use SOS to find all instances of a type, and what can see it, etc.
In general, the less you worry about memory allocation in C#, the better off you are. I would leave it to a profiler to tell me when I'm having issues with collection.
You can't create memory leaks in C# in the same way as you do in C++. The garbage collector will always "have your back". What you can do is create objects and hold references to them even though you never use them. That's a code smell to look out for.
Other than that:
Have some notion of how frequently collection will occur (for performance reasons)
Don't hold references to objects longer than you need
Dispose of objects that implement IDisposable as soon as you're done with them (use the using syntax)
Properly implement the IDisposable interface
The main sources of memory leaks I can think of are:
keeping references to objects you don't need any more (usually in some sort of collection) So here you need to remember that all things that you add to a collection that you have reference too will stay in memory.
Having circular references, e.g. having delegates registered with an event. So even though you explicitly don't reference an object, it can't get garbage collected because one of its methods is registered as a delegate with an event. In these cases you need to remember to remove the delegate before discarding the reference.
Interoperating with native code and failing to free it. Even if you use managed wrappers that implement finalizers, often the CLR doesn't clean them fast enough, because it doesn't understand the memory footprint. You should use the using(IDisposable ){} pattern
One other thing to consider for memory management is if you are implementing any Observer patterns and not disposing of the references correctly.
For instance:
Object A watches Object B
Object B is disposed if the reference from A to B is not disposed of property the GC will not properyly dispose of the object. Becuase the event handler is still assigned the GC doesn't see it as a non utilized resource.
If you have a small set of objects you're working with this may me irrelevant. However, if your working with thousands of objects this can cause a gradual increase in memory over the life of the application.
There are some great memory management software applications to monitor what's going on with the heap of your application. I found great benefit from utilizing .Net Memory Profiler.
HTH
I recommend using .NET Memory Profiler
.NET Memory Profiler is a powerful tool for finding memory leaks and optimizing the memory usage in programs written in C#, VB.NET or any other .NET Language.
.NET Memory Profiler will help you to:
View real-time memory and resource information
Easily identify memory leaks by collecting and comparing snapshots of .NET memory
Find instances that are not properly disposed
Get detailed information about unmanaged resource usage
Optimize memory usage
Investigate memory problems in production code
Perform automated memory testing
Retrieve information about native memory
Take a look at their video tutorials:
http://memprofiler.com/tutorials/
Others have already mentioned the importance of IDisposable, and some of the things to watch out for in your code.
I wanted to suggest some additional resources; I found the following invaluable when learning the details of .NET GC and how to trouble-shoot memory issues in .NET applications.
CLR via C# by Jeffrey Richter is an excellent book. Worth the purchase price just for the chapter on GC and memory.
This blog (by a Microsoft "ASP.NET Escalation Engineer") is often my go-to source for tips and tricks for using WinDbg, SOS, and for spotting certain types of memory leaks. Tess even designed .NET debugging demos/labs which will walk you through common memory issues and how to recognize and solve them.
Debugging Tools for Windows (WinDbg, SOS, etc)
You can use tools like CLR profiler it takes some time to learn how to use it correctly, but after all it is free. (It helped me several times to find my memory leakage)
The best way to ensure that objects get deleted, or in .NET lingo, garbage-collected, is to ensure that all root references (references that can be traced through methods and objects to the first method on a thread's call stack) to an object are set to null.
The GC cannot, and will not, collect an object if there are any rooted references to it, no matter whether it implements IDisposable or not.
Circular references impose no penalty or possibility of memory leaks, as the GC marks which objects it has visited in the object graph. In the case of delegates or eventhandlers it may be common to forget to remove the reference in an event to a target method, so that the object that contains the target method can't be collected if the event is rooted.
What are the best ways to get things deleted?
NOTE: the following works only for types containing unmanaged resources. It doesn't help with purely managed types.
Probably the best method is to implement and follow the IDisposable pattern; and call the dispose method on all objects implementing it.
The 'using' statement is your best friend. Loosely put, it will call dispose for you on objects implementing IDisposable.
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