Чтобы освободить память за это отвечает сборщик мусора.
Basics of working with memory in the environment CLR:
• Each process has its own separate virtual address space. All processes on the same computer share the same physical memory and the same paging file, if any.
• By default, on 32-bit computers, each process is allocated 2 GB of virtual address space in user mode.
• Application developers only work with virtual address space and never manage physical memory directly. The garbage collector allocates and releases virtual memory for the developer on the managed heap. [konec_stroki] When writing native code, Win32 functions are used to work with the virtual address space. These features allocate and free up virtual memory for the developer in their own heaps.
• Virtual memory can be in three states:
Free - there are no references to the memory block, and it is available for allocation.
Reserved - the memory block is available for use by the developer and cannot be used for any other allocation request. However, you cannot save data to this block of memory until it is allocated.
Highlighted - a memory block is assigned to physical storage.
• The virtual address space can become fragmented. This means that there are free blocks, also known as gaps, in the address space. When a virtual memory allocation request is made, the Virtual Memory Manager must find one free block of sufficient size to fulfill the allocation request. Even if the system has 2 GB of free space, the 2 GB allocation operation will fail if the space is not located in the same address block.
• Memory can run out if you run out of virtual address space for reservation or physical space for allocation.
The paging file is used even if the lack of physical memory (that is, the need for physical memory) is small. When the physical memory shortage first increases, the operating system must free up space in physical memory to store the data, and it backs up some of the data in the physical memory to the paging file. This data is not unloaded until it is necessary, so you can encounter paging in situations with very little lack of physical memory.
Conditions for garbage collection
Shortly:
If there is not enough space in the managed heap to accommodate the requested object, garbage collection begins.
Подробнее:
garbage collection occurs when one of the following conditions is true:
• There is not enough physical memory in the system. This can be determined by notifying the operating system that memory is low or by a host message that it is out of memory.
• The memory used by objects allocated on a managed heap exceeds the allowed threshold. This threshold is continuously adjusted during process execution.
• the method is called
GC.Collect. In almost all cases, you will not need to call this method because the garbage collector runs continuously. This method is mainly used for unique situations and testing.
Guided heap
After initialization by the environment CLR The garbage collector allocates a memory segment for storing and managing objects. This memory is called a managed heap, as opposed to the operating system's own heap.
A managed heap is created for each managed process. All threads in a process allocate memory to objects on the same heap.
To reserve memory, the garbage collector calls the Win32 VirtualAlloc and reserves one memory segment at a time for managed applications. The garbage collector also reserves segments as needed and returns the released segments to the operating system (clearing them of all objects) by calling the function Win32 VirtualFree.
Importantly! The size of the segments allocated by the garbage collector depends on the implementation and can be changed at any time, including with periodic updates. Your app should not make any assumptions about the size of a particular segment, rely on it, or attempt to adjust the amount of memory available to allocate segments.
The fewer objects are distributed in the pile, the less the garbage collector will have to work. When placing objects, do not use rounded values that exceed the actual needs, for example, do not allocate 32 bytes when only 15 bytes are needed.
Garbage collection, when it is running, frees up memory occupied by unused objects. The release process compresses the objects in use so that they move together and removes the space occupied by unused objects, thus reducing the heap. This ensures that objects distributed together remain in the managed heap side by side to preserve their locality.
The degree of intervention (frequency and duration) of garbage collections depends on the number of distributions and the memory stored in the managed heap.
A heap can be thought of as a collection of two piles: a bunch of large objects and a bunch of small objects.
The large object heap contains very large objects as small as 85,000 bytes in size. Objects in a heap of large objects are typically arrays. An object instance is rarely very large.
Generation
The pile is organized into generations, which allows it to process long-lived and short-lived objects. Garbage collection basically comes down to destroying short-lived objects, which usually only occupy a small portion of the pile. There are three generations of objects in the heap.
Generation 0. This youngest generation contains short-lived objects. An example of a short-lived object is a temporary variable. Garbage collection is most often performed in this generation.
Newly distributed objects form a new generation of objects and implicitly are generation 0 assemblies unless they are large objects, otherwise they fall into a bunch of large objects in a Generation 2 assembly.
Most objects are destroyed in garbage collection for generation 0 and do not survive to the next generation.
Generation 1. This generation contains short-lived objects and serves as a buffer between short-lived and long-lived objects.
Generation 2. This generation contains long-lived objects. An example of long-lived objects is an object in a server application that contains static data that exists for the duration of the process.
Garbage collections are performed for specific generations when appropriate conditions are met. Assembling a generation means collecting objects in that generation and in all relevant younger generations. Generation 2 garbage collection is also called full garbage collection because it destroys all objects in all generations (that is, all objects in a managed heap).
When used
reference types, they will also be allocated a place in the stack, only there will be stored not a value, but an address on the memory site in heap. In the
heap the values of this object will be located.
If a class object is no longer used, clearing the stack also clears the memory reference, but this does not immediately clear the memory portion itself on the heap.
When
garbage collector (garbage collector) will see that there are no more references to this part of the memory, it will clear the memory.
In the method
CreateCountry an object is created Country.
Using the operator
new in the heap to store the object
CLR allocates a memory area. And in the stack adds an address to this memory area.
In the main method
Main we call the
CreateCountry. And after CreateCountry will work, the stack space is cleared, and the garbage collector cleans the memory area previously allocated for the storage of the country object.
The garbage collector does not start as soon as a reference to an object hosted on the heap is removed from the stack. it starts at a time when the environment
CLR will detect a need for this, for example, when a program requires additional memory.
As a rule, objects in the pile are not located one after another, there may be voids between them. The pile is quite fragmented. Therefore, after the next garbage collection is cleared, the remaining objects are moved to a single contiguous block of memory. At the same time, the links are updated so that they correctly point to the new addresses of the objects.
It should also be noted that
for large objects there is a bunch of - Large Object Heap. Objects larger than 85,000 bytes are placed in this heap. The peculiarity of this heap is that during garbage collection, memory compression is not carried out due to the high costs associated with the size of objects.
Although it takes time to compress the occupied space, and the application will not be able to continue working until the garbage collector is working, however, thanks to this approach, the application is also optimized. Now to find a free place in the heap environment
CLR no need to look for islands of empty space among occupied blocks. It only needs to refer to the heap pointer, which indicates a free area of memory, which reduces the number of accesses to memory.
In addition, in order to reduce the costs of working as a garbage collector, all objects in the pile are divided into generations. In total, there are three generations of objects: 0, 1, 2.
Generation 0 includes new objects, who have never been subjected to garbage collection. Generation 1 includes objects that have survived one build, and Generation 2 includes objects that have passed more than one garbage collection.
When the garbage collector gets to work, it first analyzes the objects from generation 0. Those objects that remain relevant after cleaning are upgraded to Generation 1.
If additional memory is still needed after processing generation 0 objects, the garbage collector proceeds to the objects from generation 1.
Those objects that are no longer referenced are destroyed, and those that are still relevant are promoted to generation 2.
Because objects from generation 0 are younger and are often located in the address space of memory next to each other, then their removal takes place with the least cost.
Inference: because of generations,
newer objects (like local variables) will be deleted more quickly[/bgcolor] and older objects (such as application objects) will be deleted less frequently.
Garbage Collector Functionality in the Class Library .NET represents a class GC. Through static methods, this class allows you to access the garbage collector. As a rule, there is no need to use this class. The most common use of it is garbage collection when working with unmanaged resources, with intensive allocation of large amounts of memory, at which they need to be freed up just as quickly.
Using overloaded versions of a method GC.Collect You can fine-tune garbage collection. So, its overloaded version takes as a parameter a number - the generation number, up to which it is necessary to perform cleaning. For example GC.Collect(0) - only generation 0 objects are deleted.
Another overloaded version also takes a second parameter - enumeration GCCollectionMode.
This enumeration can take three values:
Default: default value for this enumeration (Forced)
Forced: causes garbage collection to run immediately
Optimized: allows the garbage collector to determine whether the current moment is optimal for garbage collection
For example, immediate garbage collection up to the first generation of objects:
GC.Collect(1, GCCollectionMode.Forced);