开发者

Why does my Winforms program reserve so much virtual memory?

开发者 https://www.devze.com 2023-02-24 06:31 出处:网络
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

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;开发者_如何学C
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!


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.


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.


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


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


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消