8

I have a C#/.NET 4.0 application that when I start it up shows two windows with about a dozen controls. When I run my program (Debug or Release doesn't matter), before I even do anything in it, I see in Task Manager/Resource Monitor that my program already has upwards of 450MB of private memory. I realize Task Manager isn't the most reliable way of measuring memory usage, but it is one of the most visible to my users.

When I run the VS2010 .NET Memory Allocation performance analysis, for a full run of my program, it reports about 5MB of RAM actually allocated for managed objects (my program normally uses a few unmanaged objects as well, but they are very small and to simplify this investigation I've disabled them, though to no notable effect). Likewise, if I call EmptyWorkingSet() from psapi.dll after my main form has been shown, my private memory drops to ~3.5 MB.

I've already looked at the questions about memory footprints here and here, but those questions seem to be dealing with programs that show up as a couple dozen Megabytes. My program shows almost 500MB, which looks a lot more worrisome.

I can't imagine all of that is from overhead; why is there such a huge discrepancy between the VS profiler and Task Manager?

Update: Interestingly enough, if I comment out a the part of InitializeComponent() that sets up the ImageLists, the number in Task Manager stays under 10MB. I have two sets of PictureBoxes and ImageLists where the PictureBox displays one of four images depending on which radio button in a radio button group is selected.

These lines of code are the ones that seem to trigger the massive memory increase:

// 
// directionImageList
// 
this.directionImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("directionImageList.ImageStream")));
this.directionImageList.TransparentColor = System.Drawing.Color.White;
this.directionImageList.Images.SetKeyName(0, "Dir1.png");
this.directionImageList.Images.SetKeyName(1, "Dir2.png");
this.directionImageList.Images.SetKeyName(2, "Dir3.png");
this.directionImageList.Images.SetKeyName(3, "Dir4.png");
// 
// modeImageList
// 
this.modeImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("modeImageList.ImageStream")));
this.modeImageList.TransparentColor = System.Drawing.Color.White;
this.modeImageList.Images.SetKeyName(0, "Mode1.png");
this.modeImageList.Images.SetKeyName(1, "Mode2.png");
this.modeImageList.Images.SetKeyName(2, "Mode3.png");

I am using ImageLists so I can use transparency. The Mode images are 100x100 and take up <26KB of disk space each. The Direction images are 208x277 by default and about 75KB on disk. I know png is a compressed format, but even uncompressed in memory I wouldn't expect hundreds of megabytes for these seven pictures.

Is there some inefficiency I'm aware of, and is there an alternate way to dynamically display pictures with transparency?

Conclusion: Something is fishy with the ImageList class. Sometimes it'll lose the alpha channel, and it was causing my program to reserve way more memory than it needed. It also was slowing down the time to draw the main form initially (both while running and in the designer).

Dumping the two ImageLists brought my program down to a much healthier 10MB of RAM. Thanks for all of the suggestions everyone!

Community
  • 1
  • 1
Troyen
  • 1,398
  • 2
  • 23
  • 37
  • Task manager isn't the most sophisticated way of measuring memory, but under the covers it uses PerfMon counters and so it should be just as accurate as any other mechanism. Note that the "Memory Usage" column in task manager is the private memory use - you can add a column for "Virtual Memory Size" under "Select Columns" (or just use `perfmon.exe`) – Justin Apr 13 '11 at 23:48
  • Actually the Visual Studio profiler is very helpful in this sort of scenarios. – Teoman Soygul Apr 14 '11 at 00:24

5 Answers5

2

My own experience with this problem is that i had 24bit images in my imageList while i had 32bit option set in imagelist's settings.

I've set 24bit in imagelist's properties and the problem has gone. That seems to be a bug which someone should post to MS =)

Sorry for my English.

1

the .Net framework was designed to run as fast as possible given the resources available. The application will continue to consume more and more memory as it in requested (and is readily available) only letting go when you specifically call the garbage collector or when another application needs the resources it is hogging.

Minimize the app and you should see a better representation of how much memory your application is using.

if you then go back to using it, it will remain at the lower resource state until it gets used and consumes again. minimize it again to see how much is actually (not) being used again. this is built into the .net frameworks memory management system.

The Lazy Coder
  • 11,560
  • 4
  • 51
  • 69
  • Just starting the program has me at ~459MB. Minimizing it shaves off a megabyte or so. I mean, I could understand if it had been running for a long time and I was allocating a bunch of stuff, but I'm confused as to why so much is reserved at the very beginning. Especially when the VS Profiler says I'm not actually allocating nearly as much. It's a discrepancy of over 450MB, so something is off. – Troyen Apr 13 '11 at 23:42
  • The poster said **450MB** not 45MB - although what you are saying is true, the fact that such a large amount of memory is being consumed is definitely indicative of some sort of problem. – Justin Apr 13 '11 at 23:44
  • Are you using graphics for your UI. or painting with Transparent backgrounds on your usercontrols.... are you allocating a lot of objects in the GUI. – The Lazy Coder Apr 13 '11 at 23:45
  • And I had the same sort of problem with my application using over a gig of memory. however my application was minimized and dropped down to 20 megs. I was however doing a lot of processing of large files in memory, and my computer had an available 8 gigs. so it took what was available to speed up performance. Initial load sounds like it could be a problem with the resources the app is requiring.... How large is the executable ? – The Lazy Coder Apr 13 '11 at 23:48
  • Between all the buttons, panels, menu items, and stuff, I've got about 80 objects, half of which are labels. I do have a few graphics with transparency - the total size of all the PNG files on disk is less than 1MB though. The largest picture is ~150x150 in size. I did notice the VS Profiler included all of the picture resources I was loading when it said my program allocated 5MB, so I don't think that's it either. – Troyen Apr 13 '11 at 23:53
  • Executable is 568KB in size. My computer does have 8GB of ram available though. – Troyen Apr 13 '11 at 23:55
  • I would recommend using up the ram with another app, and then opening up the application to see what it allocates, however 8 gigs of ram is a little difficult to actually fill. I guess im out of ideas. the application seems to small to actually require that, however if it is not a performance hit then its probably not an issue. You can try Red-Gate's memory profiler to see if the app is doing something fishy, maybe with third party dll's or something. – The Lazy Coder Apr 14 '11 at 00:10
  • Wait a minute. Using excel interop..... Try commenting that out in the app, and skip using it. See how much memory your app consumes. – The Lazy Coder Apr 14 '11 at 00:18
  • Doesn't look like it's excel. I seem to have narrowed it down to my ImageLists after all. Original post has been updated with details. – Troyen Apr 14 '11 at 00:45
1

Someone explained few reasons where memory jumped from 34 MB to 145 MB: Finding the true memory footprint of a Windows application

Community
  • 1
  • 1
Priyank
  • 10,503
  • 2
  • 27
  • 25
0

First up, have you tried Debug Diag? It will analyse a dump of your process and give some nifty graphs memory which might help you figure out who has allocated all that memory.

Also, check to make sure that neither your compiled .exe or any of your referneced / loaded assemblies is very large - it is entirely possible that all ~500MB is just loaded dlls. This might happen if (for example) large resources have been embedded into the assembly.

Justin
  • 84,773
  • 49
  • 224
  • 367
  • I'm trying to check out Debug Diag now. As mentioned in the comments above, my exe is 568KB in size. I import some functions from four unmanaged DLLs that are not embedded in my program with a combined total size of ~1MB. I reference the Excel Interop stuff, but that's about it. – Troyen Apr 14 '11 at 00:00
  • @Troyen Also [VMMap](http://technet.microsoft.com/en-us/sysinternals/dd535533) (mentioned in the post that Priyank linked) looks to be very useful for this sort of thing too. – Justin Apr 14 '11 at 00:05
0

png's have transparency already. Just make the white a transparent color and save the image. Then use them normally.

The Lazy Coder
  • 11,560
  • 4
  • 51
  • 69
  • I originally had an imagelist because I couldn't get some of the white parts in the images to show up as transparent. I finally found a tool to do that and just loaded my pictures from the resources, dumping the ImageLists. Program is now down to a much healthier 10MB, and even the designer is a lot snappier. Between the alpha channel occasionally getting corrupted and the high memory allocation, looks like something is up with the ImageList class. Thanks for all the help. – Troyen Apr 14 '11 at 16:34