Why collect garbage?

Just about everything that happens in a Windows application uses some of the host PC’s memory resources. This is quite obvious in the case of a database application or a spreadsheet storing its data in memory, but it’s equally true of most other resources too. Whenever a graphics application draws a rectangle on the screen, it must first obtain a buffer in video memory to hold the pixels; whenever a file is sent over the network, the copy process first obtains a buffer in memory to hold data being sent to the network adapter; even writing data to disk will usually allocate some memory buffers to hold the data being written. Whenever the .NET Framework creates an instance of a class, this too consumes a variety of memory resources. In all these cases, the application begins by requesting some resource from the operating system, performs some processing on that resource (for example, displays the rectangle or sends the data buffer to the network port) and then, when completed, releases the resource back to the OS for reuse.

Why collect garbage?

Under Win32, the applications programmer is responsible for explicitly acquiring all resources, using them correctly (for example, never trying to use a resource that’s already been released) and for releasing them when no longer needed. For a complex application, managing all this resource allocation is a major problem, and failing to release some resource after use will create a memory or handle “leak” that’s a frequent cause of application crashes. Handles and memory are both finite resources, and once they’re all tied up the application or service may stop working. Sometimes, just stopping and restarting that process or service will solve the problem (temporarily), but other times you’ll need a reboot – something most server administrators try to avoid.

To detect such leaks in memory and handles, start out by simply monitoring the Total Commit Charge value you see at the bottom left of Task Manager’s Performance tab. If you click on the Processes tab and use the View/Select Columns menu, you can also monitor individual processes’ memory and GDI Object usage. For a more fine-grained analysis, use the Performance Monitor to detect leaks in memory and handles.

Fortunately, all of this is rarely necessary with .NET applications, because Microsoft built proper memory management into the .NET Framework, and in particular automatic garbage collection. Garbage collection frees the programmer from having to worry about memory allocation and deallocation (although not quite completely, as we’ll see later). This not only improves programmers’ productivity no end, since writing the memory management for a complex application is hard work, but also creates far more reliable applications and services.

Memory management in .NET

To understand garbage collection, you first have to understand how .NET allocates memory. Whenever an application needs a block of dynamic memory for whatever reason, .NET allocates blocks from what’s known as the “managed heap” – a large area of memory owned and managed by the .NET Framework, which it shares among all the .NET applications running on the computer. From here, .NET keeps track of the usage of each of these memory blocks and reclaims them when they’re no longer in use – the act of garbage collection itself.

The screenshot below shows you the managed heap, with three objects allocated called A, B and C. In addition, .NET maintains a pointer to the first free chunk of memory in the managed heap, which is shown as Next Object (before). When an application asks for a block of memory to store the Next Object, .NET will advance this pointer by the size of the newly allocated block and pass the block’s starting address back to the requesting application. This makes memory allocation very simple, and therefore very fast. By comparison, memory allocation in a traditional C program is painfully slow, requiring the Memory Manager to walk the length of a linked list of memory blocks until it finds one big enough to satisfy the request. This block then gets divided into two parts: one to satisfy the memory request and the remainder being put back onto the linked list as a smaller chunk. This process is more complicated and much slower than allocation under .NET.

Disclaimer: Some pages on this site may include an affiliate link. This does not effect our editorial in any way.

Todays Highlights
How to See Google Search History
how to download photos from google photos