This is the fourth day of my participation in the August More text Challenge. For details, see:August is more challenging

The introduction

In the oldies, C/C++ required the programmer to manually free memory. C# introduced garbage collection (GC) to solve the problem of heap freeing, the mental burden of manually managing memory and the bugs that can occur when it is not managed properly. However, when an application’s GC comes up with collection pressures, especially the allocation and release of large object heaps. Application performance will degrade. Today, we are going to learn how to relieve GC stress

Use the Struct

Look at some code:

public struct BinaryTree
{
    public int Left { get; set; }
    public int Right { get; set; }}public class BinaryTreeReference
{
    public int Left { get; set; }
    public int Right { get; set; }} [BenchmarkDotNet.Attributes.MemoryDiagnoser]
public class Program{[Benchmark]
    public void AllocationStruct()
    {
        List<BinaryTree> binaryTrees = new List<BinaryTree>(10000);
        for (int i = 0; i < 10000; i++)
        {
            binaryTrees.Add(newBinaryTree { Left = i, Right = i }); }} [Benchmark]
    public void AllocationClass()
    {
        List<BinaryTreeReference> binaryTrees = new List<BinaryTreeReference>(10000);
        for (int i = 0; i < 10000; i++)
        {
            binaryTrees.Add(newBinaryTreeReference { Left = i, Right = i }); }}static void Main(string[] args){ BenchmarkRunner.Run<Program>(); }}Copy the code

StructBinaryTree (structBinaryTree) and ClassBinaryTreeReference (structBinaryTree) Then loop 1000 times to add them to the List

A struct is a value type, only its entire memory is stored in a List, and a class is a reference type. List stores it by allocating 10,000 objects and storing references to those objects in an array. That’s a lot more complicated than struct

Here are the results of the benchmark:

As you can see from the above test, the AllocationStruct method is nearly five times faster and also reduces the memory allocation (only 78 KB). Reduced GC pressure

When to use struct?

Struct is a value type, so after looking at the above test, some of you might be wondering, struct is so strong. I don’t need class anymore!

See below for some advice on when to use Strcut:

  1. Use strcut when you store a small number of type fields
  2. When this variable has a long lifetime, we should use class. For example, the variable needs to be passed through multiple methods
  3. Class should be used when you need to store more than a few thousand objects
  4. Classes should be used when you need to store references other than strcuts (because value copying occurs when structs are passed to other methods)

Reduce packing operations

Try to minimize casting value types to reference types, such as:

The BinaryTree you just created is of type value, and the second parameter to console.writeline () is of type Object. For this kind of problem, we usually use generics to solve it (more on this later).

conclusion

In order to reduce the number of GC runs, reduce program stress. Summarize the following points for optimization:

  1. Try to make reusable objects reusable, such as using singletons
  2. For variables with shorter life cycles, you can use strcut instead of class
  3. Try to avoid allocating large objects
  4. Using object pools