Reputation: 61433
I've implemented Dispose
...everywhere that supports it. I am removing all event handlers. I'm not calling native code.
I even iterate through every dictionary and set the values to null and call .Clear() on all the items.
Question:
How can I figure out where my code is leaking?
I first discovered the leak by running it in test overnight. It uses a fixed amount of memory so it should grow and then become somewhat static. I then made the foreground thread display memory like this:
if (key.KeyChar == 'g')
{
long pre = GC.GetTotalMemory(false);
long post = GC.GetTotalMemory(true);
Console.WriteLine("{2} Pre:{0} \tPost:{1}", pre, post, System.DateTime.Now);
GC.Collect();
}
I ran this several times (over several hours, pressing "g" once in a while) and saw an ever-increasing number.
Upvotes: 2
Views: 166
Reputation: 3490
I just had the same problem in my c# application and used (actually the trial Version) of dotTrace memory profiler which was very helpful.
It still took some time to localize the actual lines of code where the leak occurred. So do not expect that tool to immediately identify the culprit right away.
Upvotes: 1
Reputation: 73554
There's an article that describes how to do it using SOS.dll here and a more comprehensive one here.
Depending on the version of Visual Studio you're using (Premium or Ultimate), you can also use the normal Code Analysis tools to help find issues in your code that can lead to memory leaks. (Details here)
Of course, in managed code, memory leaks are a bit different than they are in unmanaged code. In unmanaged code, where you allocate and deallocate memory explicity, memory leaks are caused by failing to deallocate the memory.
In .NET, a memory leak comes from hanging onto an object longer than intended. This can largely be avoided simply by following best practices of using the using statement where possible, and by carefully planning the scope of your variables.
Upvotes: 1
Reputation: 4330
Make sure you use
try
{
}
finally
{
youDisposableObject.Dispose();
}
or
using (yourDisposableObject) {}
to every object you implemented "Dispose"
if you implemented finalizers to some of the objects without any need, remove them
if you still can't fix it after that, you will have to use a memory profiler
Upvotes: 1
Reputation: 18815
The best way to track this down is to use a memory profiler...There are lots to choose from.
Upvotes: 1