Groups | Blog | Home
all groups > dotnet performance > january 2007 >

dotnet performance : when will .net application free the committed memory (or VM)


Surain Shen
1/4/2007 2:36:47 AM
It's known, that .net app alloctes a block of memory and managed itselsf
(or by GC), and when gc do collect, it may not free the committed memory
immediately.

Who'd like tell me when will it REALLY free the memory. Any reply is highly
appreciated!

Willy Denoyette [MVP]
1/4/2007 10:50:08 PM
[quoted text, click to view]

It's important to understand the role of the GC, the GC is not a memory allocator, it's a
private heap manager, it controls and manages the "managed" object allocations by
collecting and compacting the generational heap(s), but the heap "segments" allocated from
the process heap are not under control of the GC, this is the task of the CLR's memory
allocator.
Without going too much in detail here is what happens, at the start, the CLR (memory
allocator) reserves two segments for the GC heaps (one for gen0, 1 , 2 and one for the Large
Object heap) from the OS, both of these segments are 16MB in size for the WKST version of
the CLR and two times 32 MB for the server version.
When a new object allocation hits a guard page in it's current segment, the GC will force a
collect/compactation run, and if after this run, the object allocation still hits the guard
page, then will the GC request the CLR for more memory, and the CLR memory manager will
request the OS for another segment of 16 or 32 MB. The GC can continue to allocate objects
from this new heap segment.
If after this, it happens that all objects are moved back to the initial segments after a GC
compactation run, the memory allocator is free to return that segment to the OS. Whether
this happens depends on a number of heuristics, like memory pressure GC type and object
allocation/de-allocation frequency, in general the memory allocator does return the excess
segments unless it is requested by the OS memory manager, or when a memory threashold is
reached.

Willy.


Mike Powell
1/5/2007 1:26:33 PM
Hi,
Each object or reference that is no longer used is marked for collection,
but the memory is not freed up straight away, garbage collection starts
automatically when the memory is running low or when triggered
programatically.
Once collection is started the GC goes through the heap in a linear fashion
and "de-allocates" objects that are not marked as being used, certain
objects need to have their Finalize() method called before they can be
destroyed.

a generation is the time between collections, generation 0 is the youngest
and since the heap is a stack, G-0 will be shortest lived (unless of course
an object is being used when a collection is started, in this case, it moves
up a generation. The frequency of the collections varies, however in general
G-0 is PARTIALY collected every second, G-1 every 10 partial collections of
G-0 and a complete collection is triggered after about 10 partial
collections of G-1

Mike Powell
www.ramuseco.com

[quoted text, click to view]

Phil Wilson
1/5/2007 1:43:30 PM
I think this question comes down to when, if ever, does the managed heap get
reduced in size and the memory deallocated and returned to the OS. I don't
know the answer, but experience suggests that the answer is "hardly ever".
--
Phil Wilson
[Microsoft MVP Windows Installer]
[quoted text, click to view]

Chris Mullins [MVP]
1/5/2007 3:25:18 PM
[quoted text, click to view]

I'm not sure about the actual heap size, but we frequently see the Working
Set size (as reported by Task Manager) be reduced.

If I go through the excersize in our XMPP server to Log in 10,000 users I'll
see the memory on the server jump up to 320 megs or so. When I log the users
out, the memory goes down a fair bit.

--
Chris Mullins, MCSD.NET, MCPD:Enterprise, MVP C#
http://www.coversant.net/blogs/cmullins

Phil Wilson
1/8/2007 1:15:12 PM
I believe the OPs question is directed at individual processes. At that
level, a managed process could build a huge managed heap due to (say)
initialisation code. Then the app releases a lot of that memory but still
has that huge managed heap, so its Private Bytes value is still very large
but might be mostly unused managed heap. Does some of that unused managed
heap memory ever get returned back to the system? That's the issue.
--
Phil Wilson
[Microsoft MVP Windows Installer]
[quoted text, click to view]

Surain Shen
1/10/2007 11:01:59 PM
Hi, Willy,

Thx a lot for ur reply, I do think it hits my question well:)

There is a further question, but first pls have a glance at my story:

I had a winform app which consume much more memory than a similar app of
the competitor which looks written by VC. Compare the "VM Size" and "Mem
Usage" measure value in the task manager, my app always be twice over the
competitor's. As a result, the customer ask us to try decrease the memory
usage to a reasonable range, otherwise ...

I had tried to do somethings such as releasing the reference, disposing,
and I even find anonymous method will increase memory usage a bit, and
etc., but it seems the memory usage only decrease a little...

Ok, my final question is how can I decrease the memory usage obviously?
Of course, I and my customer known that .Net app will consume more memory
than the similar app which written by VC. We still hope to improve that
problem.

In addition, the VM Size of the .Net app and the VC app are about
120m/60m, and we hope to cut it down to 90m.

Best regards,

Surain Shen

"Willy Denoyette [MVP]" <willy.denoyette@telenet.be> wrote in
news:ub#KMpEMHHA.3952@TK2MSFTNGP02.phx.gbl:

[quoted text, click to view]
Willy Denoyette [MVP]
1/15/2007 12:48:48 AM
[quoted text, click to view]

Ask, the customer to remove some RAM from it's boxes, seriously why does an end user cares
about this?
Managed applications have a slightly larger memory footprint than comparable unmanaged
applications, the reason is the size of the CLR, it's managed heap and the size of the
loaded FCL (especially Windows Forms). This is something you can't get around, you need to
accept this, the larger footprint (because of the GC and the large heap) has numerous
advantages, the CLR makes better use of the available memory resources, so does the FCL
offer a rich set of API's, that means that you can build real complex applications in
managed code that don't consume much more (say the difference won't be larger than 10Mb)
memory space than a comparable native application, you get what you paid for, really.

[quoted text, click to view]

Why, would you even try to do this, the OS will do it when there is a need for memory by
other applications.

[quoted text, click to view]
What problem? It's not difficult to consume a lot more memory when coding in a managed OO
language, it's up to you to watch your allocation algorithm and watch out for
over-consumption. Watch out for some OO designs, they tend to be the cause of
over-consumption, take care about Arrays and ArrayLists or container classes using Arrays as
backing store (or generic containers), don't use self expanding containers, pre-allocate
Arrays and List's whenever you can (you can most of the time). Otherwise stated, measure and
measure again. Use the CLR or another profiler, watch your allocation patterns, make sure
you apply a "dispose "pattern when needed, take special care about unmanaged code calls and
unmanaged memory resource usage. But keep in mind that you won't get (you don't need to) at
the level of unmanaged code, tell your customer that a similar application written in
assembly will probably use even less memory than the C equivalent, but it's price will be a
tenfold.



Willy.
AddThis Social Bookmark Button