Reducing memory usage of .NET applications?

77,164

Solution 1

  1. You might want to check out Stack Overflow question .NET EXE memory footprint.
  2. The MSDN blog post Working set != actual memory footprint is all about demystifying the working set, process memory and how to perform accurate calculations on your total in-RAM consumption.

I will not say that you should ignore the memory footprint of your application -- obviously, smaller and more efficient does tend to be desirable. However, you should consider what your actual needs are.

If you are writing a standard Windows Forms and WPF client applications which is destined to run on an individual's PC, and is likely to be the primary application in which the user operates, you can get away with being more lackadaisical about memory allocation. (So long as it all gets deallocated.)

However, to address some folks here who say not to worry about it: If you're writing a Windows Forms application which will be running in a terminal services environment, on a shared server possibly utilized by 10, 20 or more users, then yes, you absolutely must consider memory usage. And you will need to be vigilant. The best way to address this is with good data structure design and by following best practices regarding when and what you allocate.

Solution 2

.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.

Solution 3

One thing you need to consider in this case is the memory cost of the CLR. The CLR is loaded for every .Net process and hence factors into the memory considerations. For such a simple / small program the cost of the CLR is going to dominate your memory footprint.

It would be much more instructive to construct a real application and view the cost of that compared to the cost of this baseline program.

Solution 4

No specific suggestions per se, but you might take a look at the CLR Profiler (free download from Microsoft).
Once you've installed it, take a look at this how-to page.

From the how-to:

This How To shows you how to use the CLR Profiler tool to investigate your application's memory allocation profile. You can use CLR Profiler to identify code that causes memory problems, such as memory leaks and excessive or inefficient garbage collection.

Solution 5

Might want to look at the memory usage of a "real" application.

Similar to Java there is some fixed amount of overhead for the runtime regardless of the program size, but memory consumption will be much more reasonable after that point.

Share:
77,164

Related videos on Youtube

Robert Fraser
Author by

Robert Fraser

Updated on July 08, 2022

Comments

  • Robert Fraser
    Robert Fraser almost 2 years

    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.

    • mmx
      mmx over 14 years
      Why would you care? The private working set is pretty low. Modern OSes will page out to disk if the memory is unnecessary. It's 2009. Unless you're building stuff on embedded systems, you shouldn't care about 10MB.
    • Adam Sills
      Adam Sills over 14 years
      Stop using .NET and you can have small programs. To load the .NET framework, a lot of big DLLs need loaded into memory.
    • Alex
      Alex over 14 years
      Memory Prices fall exponentially (yes, you can order a Dell home computer system with 24 GB RAM now). Unless your application is using >500MB optimization is unnecessary.
    • Jamie Clayton
      Jamie Clayton over 10 years
      Remove all unused references in your application and code Imports (VB) or using (C#), so .NET loads the minimum BCL possible.
    • Jamie Clayton
      Jamie Clayton over 10 years
      Note, the newer editions of .net include more aggressive Garbage collection. See msdn.microsoft.com/en-us/library/ee787088(v=vs.110).aspx
    • Petr
      Petr almost 10 years
      @LeakyCode I really hate that modern programmers think this way, you should care about memory usage of your application. I can say that most of modern applications, written mostly in java or c# are pretty ineffective when it comes to resource management, and thanks to that in 2014 we can run just as many applications as we could back in 1998 on win95 and 64mb of ram... just 1 instance of browser now eats 2gb of ram and simple IDE about 1gb. Ram is cheap, but that doesn't mean you should waste it.
    • mmx
      mmx almost 10 years
      @Petr You should care about resource management. Programmer time is a resource too. Please do not overgeneralize wasting 10MB to 2GB.
  • Robert Fraser
    Robert Fraser over 14 years
    IOW, the same sorts of techniques that work to reduce native code size work in .NET?
  • Brian Rasmussen
    Brian Rasmussen over 14 years
    I guess there is some overlap, but with native code you have more choices when it comes to use of memory.
  • Gwyneth Llewelyn
    Gwyneth Llewelyn about 2 years
    A more up-to-date page with Profiler information from Microsoft: docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/…