Why does my Winforms program reserve so much virtual memory? - c#

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!

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.

Related

Why does my WPF UI lag when streaming lots of IP camera's in a single instance, but not when running the same amount of streams in multiple instances?

We have created a WPF application which allows you to livestream multiple IP cameras(Mobotix). This application works fine when connecting it with a few streams. All streams are rendered correctly and without any delay.
However when we try to run the application with more than 20 livestreams, we experience problems with some steams no longer updating and the UI of the WPF application lagging.
We can fix this issue by turning down the quality and/or size of the livestreams. But unfortunately this is not acceptable as the images do not contain enough detail.
After a lot of debugging, and trying with different ways to display the steams, to no avail, we noticed that if we run multiple instances of same application each rendering a limited amount of steams (for example 3 instances with 8 livestreams each), that there are no issues with any of the instances nor the camera streams themselves.
With this information we were wondering why there is a difference with one instance of the application running 24 streams or 3 instances of the same application running 8 streams each.
Does anyone here know what causes this behavior? Is there some sort of memory limitation for each application instance? Or a limitation of some kind in the GUI thread of a WPF application? Maybe there are other things we are failing to see here?
Any help would be highly appreciated!

Part of my GUI is slow

I ran into a problem with my GUI.
My GUI has multiple parts in it.
The first one is for an image (from 500x500 to 3000x3000 and it has to update up to 4 times each seconds)
The second one is the main menu
The third one has buttons with options regarding the image. I am not showing all of them at once, I scroll through several menus and i render only the ones who are visible. (An example for the otpions is the pixelsize of the image)
I display the image inside a Viewbox which is 800x800px big. I stretch the image inside of the box with Stretch="{Binding Path=StretchMode}"
The Image I get is some kind of stream. I get multiple Images each second.
Now when I display an image, the first GUI part works fine (regardless of the image size) but the others sometimes have a heavy framedrop. I will give some examples:
Example 1:
The image is 500x500 pixel big. I can work without a framedrop and the whole gui updates correctly.
Example 2:
The image is 1500x1500 pixel big. I can work without a Framedrop and the whole gui updates correctly.
Example 3:
The image is 2500x2500 pixel big. The Image updates fast but the rest of the GUI have framedrop from 60 fps to fps and sometimes even to 1 fps.
My thoughts about this problem were:
Hardware is at its limit. But a look on the Taskmanager and CPU/RAM analysis with Visual Studios says it is allright.
It is too much to render for the GUI because 3000x3000 is big and 4 times each seconds is not slow either. After a test with loaded (I loaded them from a hdd-drive) 3000x3000 images (Same Datatype) it worked fast and without problems.
Too much changes of the GUI at once. I tried the Software with only 5 updates. Still the same problem.
Microsoft Prism event not occuring. This wasn't it either because it comes inside the Controller and is Raising the changes if there is a change. (I have a logger which writes logfiles and it is raising the Change event more than the GUI is really changing)
Usage of a different datatype. Possible but i tried out several. (BitmapSource, BitmapImage and WriteableBitmap)
Outsourcing some rendering options in another thread. Still no change.
I hope you can give me some ideas why the GUI has this behaviour.
If you need code, please tell me.
I am not using a VM.
The problem occurs on Windows 7 64 bit and Windows 8.1 64 bit (not testet on Windows 10)
My hardware differs. The problem appears on my laptop (Intel i7-4702MQ #2.2 Ghz, 8 gb ddr ram, intel board graphics) and on workpc's with different specs (the highest are: Intel Xeon with 3.5 Ghz, 128 GB DDR4 Ram and a Titan X and a 4k Monitor)
EDIT: Apologies, stack doesn't have my score high enough to comment, so comment-ish content here instead.
EDIT1: Process explorer (from Sysinternals) should be used perhaps as a low-hanging fruit to see what (if any) video resources have a high consumption. there is a tab/area in process explorer for looking at graphic resources. In process explorer you can do a 'select columns' and add GPU resources for easy viewing. Might be a good angle to try.
I would venture a guess at this point that we are dealing with a
An ETW trace with DPC data might be helpful. Also you don't mention if you are in a VM or not, a VM would make taskmanager reflect inaccurate resource consumption on CPU.
An example of how to collect such a trace is here: https://blogs.technet.microsoft.com/jeff_stokes/2012/09/18/how-to-collect-a-trace-for-audio-or-video-problems-in-windows-7/
In any event, I suspect you are looking at kernel drivers or IPC/DPC issues rather than just raw CPU consumption here. More data needs to be provided I think. (hardware specs, OS used, VM/not).

Silverlight memory issue

We have a Silverlight 5 application that runs in the browser. The application can have many layouts that the user can create. These layouts can contain grids, charts and Map controls.
Once user opens a layout, out application keeps the data for that layout even if the user goes of the layout and open another one. This was intended to make it faster to come back to an already opened layout.
The issue we are facing now that over time, the browser (IE10, IE11) reaches 1GB in size which results in out of memory exception and consequently our application starts to fall over and gets exceptions on service calls.
Now the question is:
What is the best way to manage memory in a silverlight application given that the user can open a number of layouts concurrently which can take a substantial amount of memory.
I hope I have explained my scenario well. please any suggestion would be appreciated.
Regards,
Nasir
As suggested, you are going to need to use a memory profiler to determine exactly what is going on. It is highly unlikely that a few layout pages are eating up 1 gb of memory. If I were debugging this, I would start by NOT saving the layout pages, and see if the memory usage changes.
But there is no way to know where the memory is going without doing some profiling.

How to reduce memory consumption when app is minimized for x amount of time

This is a common problem with Windows. Over the years, it's something that I've noticed and it's really aggrevating me to the point where I just don't want to make apps anymore. So I've decided to try and fix it within my own apps.
When I minimize an app (for example, Visual Studio, Windows Explorer, Internet Explorer, Chrome, or any other app ever made) and leave it there for a while, there is a huge delay (of anywhere between 3 to 20 seconds) between the time I click the icon in the taskbar until the time it has reached WindowState.Normal again.
Why is this? Why doesn't Windows suspend processes when they are minimized on the Desktop? And how can I solve this problem within my own apps?
I have thought about using a Timer. Start the timer when I minimize my app, let it run for a while and say, after about 10-15 minutes of it being minimized, if it hasn't been restored yet, start releasing some resources in the hopes of freeing up some memory - which I assume would make the response time quicker so that it doesn't feel like I'm waiting in the ER when I try to un-minimize my app. But I am not sure if a Timer is the right way to deal with this problem, and I'm not even sure if this is the right solution. All I know is that I'm getting sick of this and I need to do something.
Has anybody dealt with this before? Are there any articles out there or is there MSDN documentation that addresses things like this?
How can I better manage resources in my apps so that they don't become so slow when inactive for a little while?
This problem is common to any app. Not just mine.
Edit: I'm not sure what to do. I always make good use of using() whenever something implements IDisposable, and I just don't know how else I can try and free up some resources or speed up the response times.
The symptomes you describe seem to indicate that your machine lacks physical memory. When you minimize an application and activate another, the minimized application has many of its memory pages swapped out to disk. When you activate back the application, pages belonging to other applications are swapped out to disk and the perviously swapped out pages belonging to the application you just activated are swapped into physical memory, taking a long time due to the relatively slowness of the hard drive. Solution: Add more RAM, it's relatively cheap. If your O.S. is 32 bit, you can go up to 4GB. If your O.S. is 64 bit, whatever your motherboard supports is the limit.

C#: Need to render a form/control on an "imaginary" desktop

Okay, here's what I'm trying to do. First I'll explain the end result I'm trying to achieve in case there are other ideas on how to do this.
I'm making a screen capture utility that takes a screen shot of only one window... my window (which I have total programmatic control over). However, this window may be much larger than the desktop of the computer on which the utility will run. The height, in particular, may reach several thousand pixels on a computer with 1024x768 resolution.
So I'm trying to capture the full window even though it's much larger than the screen. That's the end result I'm trying to achieve.
One hypothetical solution to this is to render the form/control on a graphics or screen object of some sort, and take the screen shot off of that object, instead of taking a screen shot of the physical desktop.
Essentially I need to draw controls on an imaginary screen that exists only in code and memory and I don't even know what to search for, so even ideas on what to put into Google (the TRUE search engine) would be helpful.
Any ideas? Thanks in advance!
EDIT: I'm using WinForms.
You didn't mention which technology your C# application uses, I'm assuming it's either WinForms or WPF.
If your implementation uses WPF, you could simply render it to a DrawingImage with the right dimensions - or even use the printing capabilities of WPF to "print" the contents of the window to an image in memory. Here's a decent example of printing in WPF that you may be able to adapt (if you're using WPF).
With a WinForms application, it is a bit trickier, because WinForm controls don't always scale well under higher resolutions, and can exhibit alignment problems. Here's a link that describes printing a WinForm screen to an image. It demonstrates printing a UserControl, but you should be able to adapt the implementation for your purposes.
Hmm, that's very odd. Have you actually written this form yet? The Form class is extremely insistent that its Size can never be larger than the screen. I've never found a workaround for this and have never seen one posted in a WF related forum.
Anyhoo, you can't make a screen shot because you don't have enough screen. The only other option is Control.DrawToBitmap().
"Several thousands of pixels" is liable to get you into trouble with OutOfMemory exceptions on 32-bit operating systems when you try to create the bitmap. Not because you don't have enough memory but because there isn't an empty hole left in the virtual memory address space that is large enough to fit the bitmap The only good workaround for that is a 64-bit operating system.

Categories