GC flavours and memory usage.
Memory Allocation, processor bitness and number of processors
I had recently worked on an issue where the customer has noticed a high virtual memory usage by the worker process. It was more than 5 GB. The working set is around 300 Mbs. The interesting part is the memory size will bloat even if there is a single request. It turns out that whenever the first time Application domains are created, the virtual memory shot to 5 GB.
So why is this high memory usage. The process is practically doing nothing and still so muh memory usage. The answer comes from the point that there are multiple flavours of GC that are available and added with the bitness of the CPU, the memory usage will significatntly differ.
Here is the thing. The customer had a 64 bit machine with 4 logical processors. By default the server variant of GC will run. Now what happens is that when the first request comes, all the application domain get created and memory is allocated to the .net components. Specifically speaking 1 heap is allocated to 1 processor. Since there are 4 processors, 4 heaps will get created, so 4 GB of heap memory will be allocated as soon as the application domain gets created. Additionally, and LOH of 256 mb is also created and allocated per heap. This all results in a memory allocation of (1+.25)*4 = 5GB.
This behavior is because in a 64 bit process, the address space is 8TB(user mode) + 8TB(kernel mode), compared to 2GB(user mode) + 2GB(kernel mode). The process is expected to use more memory and this is a tradeoff for performance.
Having said that, there will not be a performance hit because of these allocations as all of it will not be in RAM. Only the “working set” will be in RAM and you can verify by enabling that column in task manager. So bottom line is that this behavior is OK and no performance hit will happened because of this.
server version of the GC and on 64-bit process:
initial_segment_size = 1 GB
initial_large_segment_size = 256 MB
server version of the GC and on 32-bit process:
initial_segment_size = 64 MB
initial_large_segment_size = 32 MB
workstation version of the GC and on 64-bit process:
initial_segment_size = 256 MB
initial_large_segment_size = 128 MB
Note: for server version, if there are more than 4 processors, the
initial_segment_size is cut in half.
We can change the default behaviour by making the configuration change in Aspnet.config file in the Framework folder.
More Information
Lets start with task manager as how it shows the memory usage data.
- Memory - Private Working Set = The amount of memory a process is using that can't be shared by other processes.
- Memory - Working Set = Memory - Private Working Set + the amount of memory the process is using that can be shared by other processes(eg. ntdll).
- Memory - Commit Size = Amount of virtual memory that's reserved for use by a process.
In a 64 bit process, the address space is 8TB(user mode) + 8TB(kernel mode), compared to 2GB(user mode) + 2GB(kernel mode) in a 32 bit process.
So how many flovours of GC are available in different flavours of .net?
- .net 1.1 There are 2 versions of GC, implemented in either mscorwks.dll or mscorsvr.dll. mscoree.dll loads either mscorwks.dll or mscorsvr.dll based on number of processors.
- .net 2.0 Here, mscoree.dll loads mscorwks. Both Server version and Workstation version is packaged into the single assembly. i.e. mscorwks!Svr and mscorwks!Wks.
- .net 4.0 We have a new dll altogether, CLR.dll. That has the implementations of server and workstation GC.
you can quickly see which processes have loaded a specific module by this command
C:\Users\tijujohn>tasklist /m mscorwks.dll
Image Name PID Modules
========================= ========
MsDtsSrvr.exe 2704 mscorwks.dll
MagicMouse.exe 2776 mscorwks.dll
MagicMouse.exe 2784 mscorwks.dll
DcaTray.exe 3064 mscorwks.dll
EasyAssistLaunchpad.exe 3572 mscorwks.dll
msmdsrv.exe 2424 mscorwks.dll
XobniService.exe 4196 mscorwks.dll
SQLAGENT90.EXE 5024 mscorwks.dll
OUTLOOK.EXE 5372 mscorwks.dll
PresentationFontCache.exe 9764 mscorwks.dll
InetMgr.exe 4504 mscorwks.dll
Comments
- Anonymous
May 17, 2011
Good and Simple