Look who is reserving large amount of virtual memory on 64 bit: It is . Net GC heaps

by jask2002 30. March 2012 06:47

On 64 bit window 2003/2008 servers as soon as you give any .Net (.aspx) resource requests you would notice w3wp.exe taking large amount of memory in form of Virtual bytes.

Looking in task manager we would notice W3wp.exe Process/Commit size: 380 MB

Whereas looking into perfmon virtual bytes counter or  in IIS 7 => Worker Processes.We would notice approx. 5.5 GB as virtual bytes occupied by w3wp.exe

VM


This is by Design behavior for .NET web applications. Winking smile  Let me try to explain through Debug Analysis for the w3wp.exe memory dump:

!load psscor2

Process size: 380 MB

0:000> !eeversion

2.0.50727.4959 free

Server mode with 4 gc heaps

 

We have .net 2.0 loaded with 4 processors i.e that mean we would have 4 .net GC heaps

Looking at Debug Diag Memory analyzer report we would see most of the memory is ending up in Reserved Memory region

 

Virtual Memory Summary

Size of largest free VM block   6.25 TBytes

Free memory fragmentation   21.79%

Free Memory   7.99 TBytes   (99.94% of Total Memory)

Reserved Memory   4.95 GBytes   (0.06% of Total Memory)

Committed Memory   376.27 MBytes   (0.00% of Total Memory)

Total Memory   8.00 TBytes

 

Virtual Allocation Summary

Reserved memory   4.90 GBytes

Committed memory   180.96 MBytes

Mapped memory   15.25 MBytes

 

Looking at .Net GC Heap allocation pattern through !eeheap output

 

Number of GC Heaps: 4

------------------------------

Heap 0 (00000000011df1f0)

generation 0 starts at 0x00000000ffc04460

generation 1 starts at 0x00000000ffc02488

generation 2 starts at 0x00000000ff950068

ephemeral segment allocation context: none

         segment            begin         allocated             size                   reserved

00000000ff950000 00000000ff950068  00000000ffc44d30 0x00000000002f4cc8(3,099,848) 000000003de5f000

Large object heap starts at 0x00000001ff950068

         segment            begin         allocated             size                    reserved

00000001ff950000 00000001ff950068  00000001ff9af420 0x000000000005f3b8(390,072) 000000000ff80000

Heap Size          0x354080(3,489,920)

------------------------------

Heap 1 (00000000011dfc80)

generation 0 starts at 0x000000013fa423c8

generation 1 starts at 0x000000013fa2e098

generation 2 starts at 0x000000013f950068

ephemeral segment allocation context: none

         segment            begin         allocated             size                    reserved

000000013f950000 000000013f950068  0000000140027060 0x00000000006d6ff8(7,172,088) 000000003df0f000

Large object heap starts at 0x000000020f950068

         segment            begin         allocated             size                   reserved

000000020f950000 000000020f950068  000000020f950080 0x0000000000000018(24) 000000000ffcf000

Heap Size          0x6d7010(7,172,112)

------------------------------

Heap 2 (00000000011e0710)

generation 0 starts at 0x000000017f988048

generation 1 starts at 0x000000017f96cf10

generation 2 starts at 0x000000017f950068

ephemeral segment allocation context: none

         segment            begin         allocated             size                    reserved

000000017f950000 000000017f950068  000000018080c250 0x0000000000ebc1e8(15,450,600) 000000003e4df000

Large object heap starts at 0x000000021f950068

         segment            begin         allocated             size                    reserved

000000021f950000 000000021f950068  000000021f9e00b8 0x0000000000090050(589,904) 000000000ff6f000

Heap Size          0xf4c238(16,040,504)

------------------------------

Heap 3 (00000000011e11a0)

generation 0 starts at 0x00000001bfa5fb38

generation 1 starts at 0x00000001bfa41da0

generation 2 starts at 0x00000001bf950068

ephemeral segment allocation context: none

         segment            begin         allocated             size                    reserved

00000001bf950000 00000001bf950068  00000001c1110ce0 0x00000000017c0c78(24,906,872) 000000003e2ff000

Large object heap starts at 0x000000022f950068

         segment            begin         allocated             size                    reserved

000000022f950000 000000022f950068  000000022f9980a0 0x0000000000048038(294,968) 000000000ffb7000

Heap Size         0x1808cb0(25,201,840)

------------------------------

GC Heap Size         0x317ff78(51,904,376)

 

0:000> ?000000003de5f000

Evaluate expression: 1038479360 = 00000000`3de5f000

 

0:000> ?000000003df0f000

Evaluate expression: 1039200256 = 00000000`3df0f000

 

0:000> ?000000003e4df000

Evaluate expression: 1045295104 = 00000000`3e4df000

 

0:000> ?000000003e2ff000

Evaluate expression: 1043329024 = 00000000`3e2ff000

 

Reserved everything around 4.5 GB [1038479360 bytes + 1039200256 bytes + 1045295104 bytes + 1043329024 bytes] in SOH

LOH Reserve

 

0:000> ?000000000ff80000

Evaluate expression: 267911168 = 00000000`0ff80000

 

Here is the formula for reserving memory for per heap

  • If server version of the GC and on 64-bit process:

initial_segment_size = 1 GB

initial_large_segment_size = 256 MB

 

  • if server version of the GC and on 32-bit process:

initial_segment_size = 64 MB

initial_large_segment_size = 32 MB

 

Note: for server version, if there are more than 4 processors, the initial_segment_size is cut in half.

So with 2.0 framework on 4 Processor machine on x64 bit OS

Initial virtualalloc() == 4 * (1GB + 256MB) = 5GB

 

Now since you have a x64, 4 proc box, it means that you are going to use somewhere above 5 GB of reserved address space.

This is because we want to reduce the overhead of GC triggering again and again considering the fact that we have 16 terrabytes of virtual memory

 

On a 64-bit environment as the total virtual memory limit is practically limitless[16 terabytes(8 usermode TB  + 8 kernel TB)].

Thinking of Virtual Memory as a constraint applies to the 32-bit world since we have a limit of 2GB (or 3GB with /3gb switch in c:/boot.ini),which is pretty low

 

The memory that needs to be monitored and should of concern is the working set[Direct on RAM]/private bytes[committed size], as that would be constrained by the amount of physical memory on the servers.

 

Happy Debugging!


PayPal — The safer, easier way to pay online. Has this post helped you? Saved you? If you'd like to show your appreciation. Please buy me a coffee or make a small contribution toward blog's maintenance(to keep it Ads free )

Tags: , , , ,

.Net | Debugging | GC

Comments (1) -

Julio
Julio United States
5/25/2014 6:21:33 PM #

Appreciate this post. Let me try it out.|

Reply

Pingbacks and trackbacks (1)+

Add comment

  Country flag

biuquote
  • Comment
  • Preview
Loading

About me

Hi there,

My name is  Jas and I'm currently working with Microsoft IIS/ASP.Net Escalation services.  Services

 

Tag cloud

Month List

RecentComments

Comment RSS

TextBox

 

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.