I have been spending some time with a client analyzing the performance of an existing WPF application. We have found a driver-related memory leak and I wanted to share the methodology and findings.
The WPF application in question has a bar graph, of sorts, that the user can adjust with the mouse. The bar graph contains a gripper control that the user can click and drag to adjust the height of a bar graph. Users have noticed that performing many bar graph height adjustments consumes memory, eventually to the point where the application’s performance ground to a halt. We seemed to be looking at a memory leak.
To get more information on the issue, I used the WPF Performance Suite’s Perforator Tool to take a look at the application’s use of video memory at runtime. I noticed that, when I got to the section of the application that contained the height-adjustable bar graph, but before I adjusted its height, video memory usage was already up to nearly 61 MB:
Next, I adjusted the bar graph’s height. When I returned to the Perforator Tool in the WPF Performance Suite, I noticed that video memory usage increased with every adjustment, and leveled off when I stopped adjusting the height:
I noticed right away that the video memory was not being reclaimed.
This behavior continued until about 500 MB of video memory was taken up, which is when the performance problems really started kicking in:
After some digging around, we noticed that disabling hardware acceleration and using only the software rendering pipeline made the problem go away because it used (as you can imagine) none of the video memory. Video memory usage started at 0 MB and stayed there no matter how many times we adjusted the height of the bar graph. We now believe that we’re looking at a problem with the video driver, since the problem occurs with the hardware rendering pipeline but not the software rendering pipeline.
Disabling hardware acceleration is not the ideal situation, because the software rendering pipeline is slower than the hardware pipeline, but it can help in diagnosing problems such as this. You can disable hardware acceleration during your testing by setting a registry key. A key at HKEY_CURRENT_USER\SOFTWARE\Microsoft\Avalon.Graphics called DisableHWAcceleration controls the use of hardware acceleration. The key is a DWORD, and you can set it to 1 to disable hardware acceleration and 0 to enable it. A registry file that enables hardware acceleration (which is the default) would look like this:
1: Windows Registry Editor Version 5.00
2:
3: [HKEY_CURRENT_USER\SOFTWARE\Microsoft\Avalon.Graphics]
4: "DisableHWAcceleration"=dword:0
A registry file that disables hardware acceleration would look like this:
1: Windows Registry Editor Version 5.00
2:
3: [HKEY_CURRENT_USER\SOFTWARE\Microsoft\Avalon.Graphics]
4: "DisableHWAcceleration"=dword:1
You’re going to want to use hardware acceleration whenever you can, for performance reasons, but disabling it during performance analysis can help you determine whether or not your memory leak has to do with hardware acceleration or with actual code in your application.