Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reducing memory usage of .NET applications?

What are some tips to reduce the memory usage of .NET applications? Consider the following simple C# program.

class Program {     static void Main(string[] args)     {         Console.ReadLine();     } } 

Compiled in release mode for x64 and running outside Visual Studio, the task manager reports the following:

Working Set:          9364k Private Working Set:  2500k Commit Size:         17480k 

It's a little better if it's compiled just for x86:

Working Set:          5888k Private Working Set:  1280k Commit Size:          7012k 

I then tried the following program, which does the same but tries to trim process size after runtime initialization:

class Program {     static void Main(string[] args)     {         minimizeMemory();         Console.ReadLine();     }      private static void minimizeMemory()     {         GC.Collect(GC.MaxGeneration);         GC.WaitForPendingFinalizers();         SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle,             (UIntPtr) 0xFFFFFFFF, (UIntPtr)0xFFFFFFFF);     }      [DllImport("kernel32.dll")]     [return: MarshalAs(UnmanagedType.Bool)]     private static extern bool SetProcessWorkingSetSize(IntPtr process,         UIntPtr minimumWorkingSetSize, UIntPtr maximumWorkingSetSize); } 

The results on x86 Release outside Visual Studio:

Working Set:          2300k Private Working Set:   964k Commit Size:          8408k 

Which is a little better, but it still seems excessive for such a simple program. Are there any tricks to make a C# process a bit leaner? I'm writing a program that's designed to run in the background most of the time. I'm already doing any user interface stuff in a separate Application Domain which means the user interface stuff can be safely unloaded, but taking up 10 MB when it's just sitting in the background seems excessive.

P.S. As to why I would care --- (Power)users tend to worry about these things. Even if it has nearly no effect on performance, semi-tech-savvy users (my target audience) tend to go into hissy fits about background application memory usage. Even I freak when I see Adobe Updater taking 11 MB of memory and feel soothed by the calming touch of Foobar2000, which can take under 6 MB even when playing. I know in modern operating systems, this stuff really doesn't matter that much technically, but that doesn't mean it doesn't have an affect on perception.

like image 902
Robert Fraser Avatar asked Aug 27 '09 19:08

Robert Fraser


People also ask

How does .NET manage memory?

Memory allocationGarbage Collector (GC) is the part of the . NET framework that allocates and releases memory for your . NET applications. When a new process is started, the runtime reserves a region of address space for the process called the managed heap.

Can you manage memory in C#?

C# employs automatic memory management, which frees developers from manually allocating and freeing the memory occupied by objects. Automatic memory management policies are implemented by a garbage collector. The memory management life cycle of an object is as follows.

Why is IIS using so much memory?

A healthy IIS Server will consume approximately 300 - 600 MB, maybe 700 MB RAM when busy. When it uses more than 700 MB RAM, it's telling you that: You have a lot of concurrent web users. The resources loaded on the web console are intensive.


1 Answers

.NET applications will have a bigger footprint compared to native applications due to the fact that they both have to load the runtime and the application in the process. If you want something really tidy, .NET may not be the best option.

However, keep in mind that if you application is mostly sleeping, the necessary memory pages will be swapped out of memory and thus not really be that much of a burden on the system at large most of the time.

If you want to keep the footprint small, you will have to think about memory usage. Here are a couple of ideas:

  • Reduce the number of objects and make sure not to hold on to any instance longer than required.
  • Be aware of List<T> and similar types that double capacity when needed as they may lead to up 50% waste.
  • You could consider using value types over reference types to force more memory on the stack, but keep in mind that the default stack space is just 1 MB.
  • Avoid objects of more than 85000 bytes, as they will go to LOH which is not compacted and thus may easily get fragmented.

That is probably not an exhaustive list by any means, but just a couple of ideas.

like image 171
Brian Rasmussen Avatar answered Sep 21 '22 02:09

Brian Rasmussen