I have been tasked with sharing some of things I have learned about .NET applications and how they manage memory and sharing it with the team with intent of ensuring we are better prepared to investigate issues in production and that we are not creating new ones. Concepts like Garbage Collection (GC) exist to shield us from unnecessary complexity unfortunately in doing so it can mask ideas that are important.
For me, working with a high availability custom app server and IIS, healthy memory management is incredibly important, so delving below even good and robust abstractions is critical. I have spent the last few weeks looking for the right combination of videos, articles and topics to kick of this learning exercise. The first one is Everything you need to know about .NET memory by Ben Emmett.
I am encouraging my colleagues to start here, and after watching this video to consider and describe the following concepts:
Each process has its own and separated virtual address space (we never manipulate physical memory directly), all processes on the machine share the same physical memory (plus the page file). The amount each process can access depends on the whether you are using a 32 or 64 bit machine. 4 GB (2GB user mode) for 32-bit Windows, 16 terabytes (8 terabytes user mode) for 64-bit Windows.
If you are writing managed code the GC is the one who allocates/frees virtual memory on your behalf. Even though this is handled for you, for the sake of speed, virtual address space can and will get fragmented, so it is possible and likely that you get free blocks between used address spaces, otherwise known as fragmentation.
Virtual memory can also be in different states:- free, reserved and committed.
You can get out of memory if you are running out space to reserve, or space to commit. In the age of 64bit processors out of memory is most likely to mean unable to commit (out of physical memory rather virtual memory).