Welcome to MSDN Blogs Sign in | Join | Help

Maoni's WebLog

CLR Garbage Collector
Difference Between Perf Data Reported by Different Tools – 2

Managed Heap Size

We have both .NET CLR Memory perf counters and SoS extensions that report manged heap size related data.

Difference 2

There are a few .NET CLR Memory counters that are related to the managed heap size:

# Total Committed Bytes

# Total Reserved Bytes

I explained what these counters mean here.

Now, how are they related to the values you see when you do a !SOS.eeheap –gc?

0:003> !eeheap -gc
Number of GC Heaps: 1
generation 0 starts at 0x01245078
generation 1 starts at 0x0124100c
generation 2 starts at 0x01241000
ephemeral segment allocation context: (0x0125a900, 0x0125b39c)
 segment    begin allocated     size
001908c0 793fe120  7941d8a8 0x0001f788(128904)
01240000 01241000  0125b39c 0x0001a39c(107420)
Large object heap starts at 0x02241000
 segment    begin allocated     size
02240000 02241000  02243250 0x00002250(8784)
Total Size   0x3bd74(245108)
------------------------------
GC Heap Size   0x3bd74(245108)

The allocated column indicates the end of the last live object on the segment. So for gen0 and LOH it changes as the managed threads allocate, unlike the .NET CLR Memory counters which only reflect the end of the last live object on the segment when the last GC’s happened (at the end of last GC).

The # Bytes in All Heaps counter  under .NET CLR Memory counter is kind of misleading. The explanation says it’s the bytes in “all heaps” but really it’s gen1+gen2+LOH in CLR 2.0, so it doesn’t include gen0 ‘cause most of the time gen0 size is 0 right after a GC. So if you break into your process under the debugger and use the !sos.eeheap –gc command you will most likely get a value that’s the same as this counter. But if you break between 2 GCs the value you get from !eeheap –gc will always be larger than the value of this counter.

If you are concerned with the true amount of memory that the managed heap commits (which is usually what you need to worry about) you should use the # Total Committed Bytes counter.
Posted: Tuesday, December 12, 2006 4:14 PM by maoni

Comments

Jason Haley said:

# December 12, 2006 11:25 PM

Marteen Rojo said:

Dear Maoni,

its with great interest that I've been reading your blog posts.

We are sizing/capacity planning my company's application's performance,

So for each application-centric object we create, memory is measured (so as to figure out how many we can create etc.).

Can you explain the difference between these 2 performance counters?

Process\Private Bytes and

.NET CLR Memory \ # Total committed Bytes ?

I thought that Process\Private Bytes showed , basically, how much memory was actually in use, but now I think the "# Total committed Bytes" is what should be measured.

Sincerely,

Marteen

# December 28, 2006 4:15 PM

maoni said:

Marteen, the .NET CLR Memory\# Total Committed Bytes is only the private bytes used for *managed heap*. In your process you have other things that will contribute to the private bytes like if you make native allocations either yourself or in some modules that you use and Process\Privates Bytes shows all private bytes used in the process.

# December 29, 2006 4:35 AM

leoleo said:

This is really interesting, so it looks like the heap sizes from perf counters will always be smaller than !sos.eeheap -gc. For one it doesn't include gen0 but that's a small portion relatively speaking but also it is post GC data which means the heaps are all "cleaned up". Does that sound about right?

# January 15, 2007 10:32 PM

maoni said:

Yes.

# January 15, 2007 11:05 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Page view tracker