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?
问题:
回答1:
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.
回答2:
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.
回答3:
heres a method i use:
http://www.codeproject.com/KB/dotnet/Memory_Leak_Detection.aspx
回答4:
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.
回答5:
Code project currently has a link to an app specifically for finding undisposed objects.
http://www.codeproject.com/KB/dotnet/undisposed.aspx
回答6:
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.
回答7:
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
回答8:
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.