views:

246

answers:

4

I notice an usual high memory size. One app i wrote is a console app that uses <50lines and simply downloads a series of files solely using WebRequest. Another app that isnt trivial (mysql, dls, multithreads, listbox with 100 items). The first uses 21 mb (debug, ide), the other uses 39mb(debug, ide). I also have another app polls my site (also using WebRequest) for a status update which sits on my tray and notifies me using 26mbs(release, not ran through ide).

Why are these so high? i know i written a C++ app alike above using curl that ran <2mb and my largest C++ prj is 11mb which loads in a 100kb dll and a 200kb binary (using directx with win32 icons and sound). How can i compile my C# code so its more space friendly. I would like to deploy these to a server which may only have 128 or 256mb ram and a few of these apps would kill it.

Site Note: I ran the first app mentioned (console DLer) in release mode (and through the ide) and it jumped up to 32mb. Why!?! thats more confusing.

+5  A: 

Honestly, don't worry about the foot print of managed code until it you are able to measure cases where its memory size is creating issues. There are a lot of different things going on that the CLR does when you launch a .NET assembly, too much to list here, but see http://weblogs.asp.net/pwilson/archive/2004/02/14/73033.aspx and for many more resources see http://geekswithblogs.net/sdorman/archive/2008/09/14/.net-memory-management-ndash-resources.aspx

Take a look at this article for some insight on how you can determine what your application is really using on terms of memory because task manager doesn't show the real story http://www.codinghorror.com/blog/archives/000271.html

If you really really really want to make your assembly show in task manager with less memory than you need to ditch managed code. A way to cheat is to compile your application using something like Salamander Protector which makes your application a native executable rather than a .NET assembly.

Bob
Another way is to use the ngen tool http://msdn.microsoft.com/en-us/library/6t9t5wcf%28VS.80%29.aspx which compiles the code natively and is from Microsoft (so presumably reliable/safe).
Russell
+1  A: 

I am not an expert on the CLR, but i have noticed that the CLR allocates memory in chunks and can balloon very high even if your application doesn't use that much memory. Its kind of like the CLR likes to hold on to memory which it doesn't need so that it doesn't need to call windows to reallocate.

Check the private bytes of your application. The private bytes should be a more reasonable indicator of the memory your actually using, rather than how much the CLR is holding on to. Also, setting the MaxWorkingSet of the process seems to magically recalibrate the statistics in task manager.

System.Diagnostics.Process loProcess = System.Diagnostics.Process.GetCurrentProcess();
loProcess.MaxWorkingSet = loProcess.MaxWorkingSet;

The code above looks like a candidate for TheDailyWtf. LOL

Andrew Keith
-1: There are actual reasons that aren't guesses which are obtainable via google.
Greg D
The private bytes look much more reasonable. (6mb) and each working set is 3x bigger! :|
acidzombie24
A: 

One of the things to keep in mind is that the garbage collector won't always free memory until something else needs it. So even though your application might claim to be using 100MB of memory, in reality it may be using 50MB but the garbage collector hasn't had a reason to collect and free the rest yet.

Even the basic initialization of an application creates a lot of temporaries, which causes the CLR to allocate memory blocks for the application. As long as the system has plenty of memory the garbage collection will be pretty lazy about detecting and cleaning up the unused memory; this is a speed optimization. Don't fret, when your system starts to need more memory the garbage collection will kick up and start doing deeper scans.

Make sure you aren't manually calling the garbage collector, the more often it is called, the more objects get pushed up in to higher generations that won't be collected until the system is low on memory.

Drakonite
+2  A: 

Small .NET applications can't really compete with C/C++ applications when it comes to memory footprint for a number of reasons.

The .NET runtime is huge compared to what a native app needs for startup. In order to run a .NET app the CLR has to be in memory. Not only will it have to load components such as the JIT compiler, the GC and so forth, it also needs a number of internal data structures. E.g. even the simplest .NET application has three AppDomains, two used internally by the CLR and one for the application itself.

Furthermore assemblies are loaded when they are referred. Even though the methods are not jitted until needed, the assembly itself uses a lot of address space when loaded. When the code is jitted at some point, it is stored once more in memory as native code. So essentially compiled code is present twice in a .NET app.

Finally the type system is a lot more elaborate on .NET compared to what you'll find in a C/C++ app. Every single object carries information about its type. This allows for reflection and other useful features, but it does come at a price.

If you want very small footprint .NET may be good enough, but it certainly isn't the most obvious choice, as you will pay for the overhead of the runtime.

Also, please see this related question http://stackoverflow.com/questions/1343374/reducing-memory-usage-of-net-applications/

Brian Rasmussen