Freigeben über


Issues with Winform Application when running in Windows 7

Here comes a blog from EMEA Windows WPF & UI Subject Matter Expert and experienced Engineer Shiva Shankar

Recently one of my customers reported a problem where his Winform application started failing with “Not enough storage is available to process this command” error when running in Windows 7. Yet, the same application works great on Windows XP.

 

That was really something interesting. So, what could be the reason? Hmm, there may be ‘n’ number of reason, but in this blog we are going to look into a particular scenario.

[Scenario Details]

  • The application is using a lot of “System.Drawing.Bitmaps” objects.

 

  • In the failure scenario you notice that lot of these objects are not disposed.

 

  • Lot of 64 Kb allocations on the native side.

 

  • The application was working fine on earlier version of OS like Windows XP.

 

The next question would be, how do I get these details?

To get this we may need to get our hands dirty with WinDBG. I am not going deep into the analysing logs using WinDBG in this blog, but I will share some basic steps , and will concentrate more on the work around here.

  • Capture a crash dump when the application fails with out of memory or related exception.
  • Open the dump in WinDBG.
  • Run “!address –summary” to get the memory details.
  • Check the memory under “<unknown>” section from the above output.
  • Run “!eeheap –gc” to get the managed memory details.
  • If the managed memory size is low compared to the total application memory, and <unknown> section memory is very large. Then we can proceed further. Else this blog is not related to the problem you are interested in.
  • Check the total number of Bitmap used in the application. To get this details run “!dumpheap -stat -type System.Drawing.Bitmap”. This will give us the total number of “System.Drawing.Bitmap” objects in the application.
  • If you see that the application is using a huge number of Bitmap objects, then this work around below may solve the problem.

[Work Around]

Yes, the below option is only a work around. This is not the actual solution to the problem. The right solution to this problem may depend on the exact scenario of your application. If the application is using lot of bitmaps intentionally, then you would need to re-architect your solution to use fewer bitmaps at a time. In case you see lot of bitmap objects which are not intentional, then you would need to work on properly disposing them when not required. I will not be able to cover the solution
details in this blog, but I will try to write a different blog on this later.

 

GDI+ 1.1 (default on Windows 7) will call into the Windows Imaging Component (WIC) to handle image rendering. WIC improves the performance and reliability of image encoding/decoding in the application, but consumes little more memory compared to GDI+ 1.0. On Windows Vista/7 operating system, we still have an option to force our application to use GDI+ 1.0 for image rendering, but starting Windows 8 this option is not available any more. As said before, this is temporary solution only.

 

We need to make the below changes to App.Config file in the application to work around the problem. If you do not see this file under your project, you can add this file using Visual Studio.

          

       1.   Right click on the project and select Add -> New Item.

       2.   Select Application Configuration file from the list.

       3.  Double the file to open it for editing.

       4. Add the changes and save it.

 

<?xml version="1.0" encoding="utf-8" ?>

<configuration>               

               
<appSettings> 

                             .

               
</appSettings>   
       
     <!-- Add this setting to force application to use GDI+1.0 version -->

                      
<dependency>

                                  
<dependentAssembly>

                                              
<assemblyIdentity type="win32" name="Microsoft.Windows.GdiPlus"

                                                                      
processorArchitecture="*" version="1.0.0.0" publicKeyToken="6595b64144ccf1df" language="*"/>

                                  
</dependentAssembly>

 </dependency> 

</configuration>

 P.S.: The above setting will make our application work similar to earlier Windows OS like XP by using GDI+ 1.0. By forcing our application to use GDI+ 1.0, we avoid the extra memory used by WIC to render bitmap, thus keeping our application memory low as compared to using GDI+ 1.1.

 Hope this helps you to earn some time to work on managing the images more efficiently and/or calling dispose properly in the application.

Written by: Shiva N Shankar

Reviewed by: David Wooden

Comments

  • Anonymous
    February 18, 2014
    Thanks that is very useful information to consider. Just one question: Can this break WPF applications? I mean does WPF depend on an specific GDI version or should it just work?