.Net Performance Tuning - Garbage Collection! ! ! The most complete garbage collection

At present, the project development is basically based on .NetCore 3.1 or above, and some rules and concepts of the old version are not listed. The garbage collection type and memory release method of the lower version will be different.

Why does the garbage collector exist?

  • The developer does not have to free the memory manually.

  • Efficiently allocate objects on the managed heap.

  • Objects that are no longer in use are reclaimed, their memory is cleared, and memory is reserved for future allocations. Managed objects automatically get clean to start with, so their constructors don't have to initialize every data field.

  • Provides memory safety by ensuring that an object cannot use the contents of another object.

Managed Heap Algebra

Overview

To optimize the performance of the garbage collector, the managed heap is divided into three generations: generation 0, generation 1, and generation 2. The purpose is to deal with short-lived objects and long-lived objects separately. The garbage collector handles the collection of short-lived objects most of the time.

The GC collection of the bottom generation will trigger the GC collection of the young generation, and the GC collection of the second generation will trigger the full GC collection.

Generation 0 (provisional generation) 1st generation (temporary generation) 2nd generation LOH (Logical 3rd Generation)
memory segment Temporary segment Temporary segment non-temporary non-temporary

The LOH (Large Object Heap) is actually in
the second generation and has an area for it on the second generation alone.
Logically called the 3rd generation |
| contains | short-lived objects, that is, newly allocated objects | short-lived objects, after being reclaimed from the 0th generation,
the unreclaimed objects are upgraded to the 1st generation. | For long-lived objects, after the first generation is collected,
the uncollected objects are upgraded to the second generation. | The size of the object >= 85,000 bytes |
| Collection conditions | The 0th generation allocated memory reaches the threshold
If the 0th generation is full, still try to create a new object
Call GC.Collect() method
1st generation GC collection | 1st generation The allocated memory reaches the threshold.
After the 0th generation collection, there is still not enough space to store new objects (in this case, the 1st generation will be collected first, and then the 2nd generation will be collected)
Call the GC.Collect method
2nd generation GC collection | 2nd generation has been allocated After the memory reaches the threshold
, there is still not enough space to store new objects after the 0th generation reclamation (the 1st generation will be reclaimed first, and then the 2nd generation will be reclaimed). The
GC.Collect method is called. The
LOH recycling condition
is reached. Condition
Large object memory allocation reaches the threshold |
| Collection method | Foreground garbage collection, the current managed thread is suspended | Foreground garbage collection, the current managed thread is suspended | Background garbage collection, the current managed thread executes normally | Same as the second generation |
| | | | | |

To determine whether an object is a large object, you can view it through the following code

var o = new Byte[85000];
Console.WriteLine(GC.GetGeneration(o));//GC2,大对象
o = new Byte[84900]; 
Console.WriteLine(GC.GetGeneration(o));  //GC0,小对象 84999仍是大对象,需要用一定量的内存空间保存指针 
var arr = new int[85000 / 4];	
Console.WriteLine(GC.GetGeneration(arr));//GC2,大对象,数组会提前开辟空间, int占32位,4个字节,85000 / 4加上指针内容会达到大对象的大小
arr = new int[85000 / 4 - 20];  
Console.WriteLine(GC.GetGeneration(arr));//GC0,小对象

threshold

When the garbage collector detects a high survival rate in a generation, it increases the allocation threshold for that generation, preventing garbage collection from running too frequently

However, after the threshold is increased, the amount of memory recovered at one time will be too high.

So the threshold is dynamically determined by the CLR to adjust the balance between the recycling frequency and the size of a single recycling memory

Garbage Collection Type

Workstation (default mode) server
Features The garbage collection thread has the same priority as the user thread and will compete with the user thread for CPU resources
Computers with only one processor will eventually apply the workstation garbage collection method regardless of whether the configuration file is modified or not Dedicated thread with garbage collection

The thread priority is THREAD_PRIORITY_HIGHEST and each CPU is allocated a dedicated thread and dedicated heap for garbage collection. Different heaps can communicate with each other
Multiple garbage collection threads work together, so server garbage collection is faster than workstation garbage collection when the heap size is the same |
| Applicable scenarios | Common scenarios | Server applications that require high throughput and scalability|

memory release

release target

GC释放应用程序不再使用的对象的内存,通过检查应用程序的根来确定不再使用的对象

应用程序的根包括:静态字段、局部变量、CPU 寄存器、GC 句柄和终结队列

release step

- 列出不可访问对象和幸存对象的地址块并**标记**
- 使用内存复制功能压缩可以访问的对象到不可访问的地址块中,就是把存活下来的对象重新排列到连续的内存块中
- 大对象通常不会压缩,因为大对象所占用的内存区域过大,移动成本太大
- 回收死空间
- 指针更正,让对象指针指向新地址,指针更正是因为压缩了对象,对象在内存中的位置发生了变化

Code tuning

  • Always call the Dispose method of the referenced object , always implement the destructor correctly in the class that implements IDisposable
  • Objects allocated in static classes are deleted in time when they are no longer used
  • Disallow injection of transient-lived objects in classes that IOC declare as singleton-lived
  • Do not create large objects unless necessary
  • Depending on the situation, use ValueTask to replace Task. Task is a reference type. CPU-intensive calls will frequently trigger the 0th generation GC recycling.
  • Reuse HttpClient whenever possible
  • Lease object space from buffer pool using ArrayPool or MemoryPool
  • Use WeakReference to reuse objects that are no longer in use but have not yet been reclaimed

Monitoring and debugging

  • Listening to garbage collection ETW events, you can view ETW events with PerfView, which is suitable for the window platform. You can also introduce the Microsoft.Diagnostics.Tracing.TraceEventnuget package in the code to monitor the specified GC recycling and other events in the code to customize the subsequent processing logic

  • Use performance monitor Perfmon.exe , for windows platform

  • Use SOS to debug, grab the dump file and use WinDbg for analysis and diagnosis, which has a wide range of applications and can see the most complete memory information

  • .Net CLI tool dotnet-counters , you can see the approximate performance index data statistics, suitable for temporary health viewing and monitoring

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324041018&siteId=291194637