Computer Software can have bugs and some of these bugs are Memory Leaks. It is usual case that if your software is a Multi-Document application you need to pay more attention on memory leaks. The main question in these applications is how I can be sure that when user will close document I will release all instances and resources related to this document? What if you already found a Memory Leak and fixed it? How you can protect yourself to be sure that after some changes you will not have this memory leak again?
I had the same thought after one of my Memory Leak fix. Do we have any software or tools which can validate that after some interaction with my application all instances are released, which I want to be released? In native world there are should be a lot of different instruments / practices to do this (I'm not an expert, but pretty sure that this is true). In managed world there are a lot of tools with names Memory Profiler, but to make them work you need to run them separately, analyze your application and after that analyze the report to find memory leaks. This can work, but I'd like to have some instrument in my application which can in runtime check my application and find memory leaks. The solution which I found is pretty simple. I store the list of WeakReferences to objects which I want to check after some interaction that they are released. Based on this I wrote Object Release Verification Framework with couple classes and interfaces. This framework is published on nuget.org as a portable library.
Let's take a look on example. At first – we need to create a new WPF Application project (I will use Visual Studio 2012), after this we need to include nuget package ObjectReleaseVerification by invoking next command in Package Managed Console (or with help of NuGet UI):
PM> Install-Package ObjectReleaseVerification
After this we need to add some code to initialize Verification Framework. It is turned off by default, and it doesn't have any notifications about memory leaks by default. The cause of the latest: some restrictions of using portable library – it is hard to find something which will work on Windows Phone, Web and Desktop platforms at the same time. The initialization code can be next:
This code turns on Object Release Verification framework only when we compile bits in Debug configuration. Also we add one Handler for verification events, which actually is a part of verification framework TextOutputVefiricationHandler. This class expects just one parameter in constructor. The value of this parameter is a function which can write strings. In my case it is debug output window.
After this I will add some logic to the application. I will emulate work of multi-document application:
This code adds simple table control and couple buttons which can add and remove tabs to this control. The code behind:
Method AddTab creates and adds new tab item to the tab control, it uses DateTime.Now as a name for the tab, we will use as a "document name" (just want to remind that I'm going to emulate a multi-document application). Our window also contains the list of all tab items. We use it just to emulate memory leaks in future. The last code line adds the new tab item to the verification framework, so it can start to track it. We use "document name" as a context. Context is a unique name, which allows us to group instances in different lists, so we can just validate instances in special list, by special context.
Method RemoveTab removes active tab from the list of all tabs and from control. Last line of code in this method validates that all instances in current context are released. The context is a document name (tab header), which we generates in AddTab. In method Verify we use delay for 1 second to be sure that Verifier will do verification when runtime will go away from the RemoveTab method. We need to be sure that all variable instances like tabItem will be out of scope, so there are will be no references to these instances. Method Verify will invoke Collect method of Garbage Collection and after that do verification, like which objects are released and which of them not.
This is how it looks:
On this screenshot I added couple tabs and after this removed one of them. As you can see in output window – verification framework shows me which objects are released.
You can implement your own verification handler. For example verification handler in next sample just shows assert when verification fails (application has memory leaks):
After this we can also add it to the collection of verification handlers:
After this let's try to comment one line in RemoveTab, so with this line we will simulate memory leak:
After we will try the same steps which we made in previous run (add couple tabs and remove one of them) we will see assert and detail information in output window:
You can take a look on this sample at https://github.com/outcoldman/OutcoldSolutions-ObjectReleaseVerification-Sample. If you will have any suggestions or comments about this framework – I'd like to hear them.