This is by Design behavior for .NET web applications.
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
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!