Large Memory Footprint for Simple .NET Apps

T

Tom

We have a VERY simple .NET C# Form Application, that has about a 23MB
Memory Footprint. It starts a window runs a process and does a regular
expression. I have done a GC.Collect to make sure that, no memory is
lying around. GC reports only 84k of allocations. Starting 5-10 of
this apps is going to start taking a considerable amount of memory. Is
there a way to reduce this?

Tom
 
W

Willy Denoyette [MVP]

And what exactly is the 23MB footprint? What Memory counters are you looking
at?

Willy.
 
T

Tom

Thats my question! What is it?! How would I find out. I am looking at
the Task Manager. The GC only reports about 84k of allocations. The
Win32 Equlivalant of this program would be less than a Meg. My theory
is it is all the memory of having the Assemblies loaded in memory.
 
W

Willy Denoyette [MVP]

Memory counters have a name,f.i.Taskmanager shows 'Mem Usage' and 'VM Size'
per default. The Performance monitor has a whole bunch of named Memory
counters. So when talking about memory consumption you should add the name
of counter you are looking at. Note that "perfmon" also has a number of CLR
specific memory counters that are more important than the Taskman counters.
For the remaining of this discussion I assume you are looking at (but I
could be wrong) Taskmanager's "VM size" , which is the 'wrong' counter to
look at when talking about RAM usage.
'VM size' shows the number of "private bytes" committed to the process, that
doesn't mean all those bytes are taking up physical memory only a part of it
is actually stored in RAM. The number of bytes currently taking up RAM is
shown in the 'Mem Usage' column, this counter is the sum of the private
bytes and shared/shareable bytes currently in RAM.
Shared/Shareable bytes are those that are effectively shared or can possibly
be shared amongst other processes, a small managed program can share some
20-30% of it's 'Mem Usage' or "Working Set" with other non 'managed'
processes and up to 40-70% with other managed processes, depending on the
type of application.
What does this all mean? Suppose you have a managed process (a small
Winforms application) taking 14MB of RAM (Mem Usage),
when starting a second instance, because of code sharing, this will only
take ~30% -70% more RAM. So you can't simply add the 'Mem Usage' counters
like you did in your original posting to calculate the amount of RAM used
when running several instances.

Now why are 'VM Size' and 'Mem Usage' values higher when compared to a
native Win32 process,?
First the CLR is loaded in a managed application, this takes up some MB of
shared/shareable pages - part of it shared with non managed applications and
almost all of it shared with other managed processes.
A winforms application loads (besides other FCL assemblies like System.dll,
Mscorlib.dll etc..) a large part of the Windows.Forms.dll assembly for the
UI main window initialization, this accounts for a few MB of shareable code
pages not loaded in an unmanaged application.
And for the 'VM Size' here a large part is 'reserved' by the GC heap, note
that only a part of it is actually taking up real memory, as the CLR
pre-allocates a portion which is not completely returned when not in use.
The same effect can be observed with unmanaged applications reserving a lot
of virtual memory as part of pre-allocation of buffers. When the GC heap
runs out op space the CLR will ask the OS for more memory and the VM Size
will grow, if this is paired with a growth of 'MemUsage', it can be an
indication of a managed/unmanaged leak, when VM size grows without ever
shrinking, it is almost certain a leak.

What is the lesson learned?
- Use the permon counters (and learn what they represent) when looking at
memory consumption.
- Use the Working Set counter for the actual RAM usage (if that's important
to you).
- Use "Private bytes" counter to watch for memory leaks (together with the
CLR GC counters to make a distinction between managed/unmanaged heap).
- Learn how Memory is managed in a NT based OS.

Willy.

PS. "Mem Usage" is "Working set bytes" and "WM Size" is "Private Bytes" in
Perfmon.
 
W

Willy Denoyette [MVP]

Oh I forgot:
What are the lessons learned?
- Yes, a managed application's memory footprint is larger than an unmanaged
, simply because the runtime is part of the process.

Willy.
 
C

Cor Ligthert

Willy,
What are the lessons learned?
- Yes, a managed application's memory footprint is larger than an
unmanaged > , simply because the runtime is part of the process.

Nothing about the contents of your message, however in my opinion is your
above statement probably always true for small programs, however not for
large programs.

There the memory use can be earned back by reusing a lot of code in a more
efficient way. That is why runtime parts where devolleped for in the first
place in past.

Just my thought

Cor
 
W

Willy Denoyette [MVP]

Cor,

True, the WS shared pages overhead stays more or less the same value (lets
say 5 -8MB) independent of the "size" of the program. The bulk of a large
program (in both WS and Virtual bytes size) is determined by the number and
size of the objects in the GC heap and the size and number of program
assemblies loaded.

Willy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top