Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET process memory usage = 5x CLR Heap Memory?

I'm trying to tackle down some memory usage issues. Overall my application collects a few data values and visualizes them using a C1 WPF charts and datagrids finally putting everything into PDF reports.

Profiling my process using YourKit I'm faced with the situation, that the CLR heap size is ~120MB (which is all fine) while the process memory size is ~580MB. This is nearly 5 times the memory consumption of my actual CLR heap size. My CLR peak size was 220MB vs. 710MB process memory allocation.

I'm well aware that there is some overhead required on my object heap, stacks and so on. In Java JVMs the typical factor I'm used to was around ~1.5x.

How can this excessive memory overhead be explained? Is the processs just allocating free spare heap space? If yes, does this explain the 710MB vs. 220MB?

like image 807
bentolor Avatar asked Apr 12 '12 10:04

bentolor


People also ask

What is the size of heap memory in C#?

The heap in . Net is a portion of memory that for practical purposes can reach a maximum of around 1.5GB for 32-bit processes and unlimited for 64-bit (again, for practical purposes), and it will indeed request memory as needed from the OS.

How much heap usage is too much?

High heap usage occurs when the garbage collection process cannot keep up. An indicator of high heap usage is when the garbage collection is incapable of reducing the heap usage to around 30%.

How do I increase the process heap size?

Just use a function like malloc() or calloc() to allocate memory dynamically. To deallocate the memory and return it to the heap, use free() . These functions will manage the size of the heap by expanding or shrinking it as needed.

What do you do when your heap memory is full?

The Heap and the Nursery When the heap becomes full, garbage is collected. During the garbage collection objects that are no longer used are cleared, thus making space for new objects.


1 Answers

A couple of additional notes here. Though I'm not exactly sure what you mean by "CLR Heap Size". Depending on the .NET Runtime you're using, there are 8 or 9 different heaps that the CLR uses - so the memory you see in the Heap Size vs. VM size accounts for some of the difference:

  1. Loader Heap: contains CLR structures and the type system
  2. High Frequency Heap: statics, MethodTables, FieldDescs, interface map
  3. Low Frequency Heap: EEClass, ClassLoader and lookup tables
  4. Stub Heap: stubs for CAS, COM wrappers, P/Invoke
  5. Large Object Heap: memory allocations that require more than 85k bytes
  6. GC Heap: user allocated heap memory private to the app
  7. JIT Code Heap: memory allocated by mscoreee (Execution Engine) and the JIT compiler for managed code
  8. Process/Base Heap: interop/unmanaged allocations, native memory, etc
  9. added in .NET 5: Pinned Object Heap (POH)

Two other items which can cause excessive memory usage are memory fragmentation (mostly occurs on the LOH or large object heap) or a high number of Threads.

There are many causes for memory fragmentation and the best way to rule this out is to use WinDbg to analyze the segment sizes for each segment on the GC Heap.

As far as a high number of threads, you have either 1MB (for x86 process) or 4MB (for x64 process) of stack space allocated for each thread that your app uses. This memory is placed in the Process/Base Heap. Therefore if you have 100 threads, you can have up to additional 100MB/400MB of memory usage.

HTH

like image 126
Dave Black Avatar answered Oct 25 '22 00:10

Dave Black