Practical tutorial on writing high-performance .NET
Reduce allocation rate
This almost needs no explanation. It reduces memory usage, which naturally reduces the pressure during GC recycling, and at the same time reduces memory fragmentation and CPU usage. You can use some methods to achieve this, but it may conflict with other designs.
You need to carefully examine each object as you design it and ask yourself:
Do I really need this object?
Is this field what I need?
Can I reduce the size of the array?
Can I reduce the size of primitives (replace Int64 with Int32, etc.)?
Are these objects only used in rare cases or only during initialization?
Is it possible to convert some classes into structures so that they can be allocated on the stack or become part of an object?
Am I allocating a large amount of memory but only using a tiny fraction of it?
Can I get relevant data from other places?
Little story: In a function that responds to requests on the server side, we found that some memory larger than the memory segment will be allocated in a request. This causes us to trigger a complete GC for every request. This is because the CLR requires all generation 0 objects to be in one memory segment. If the currently allocated memory segment is full, a new memory segment will be opened, and the original memory segment will be opened. The memory segment is recycled for 2 generations. This is not a good implementation since we have no other way than reducing memory allocation.
The most important rule
There is a basic rule for high-performance programming with garbage collection, which is actually a guiding rule for code design.
The objects to be collected are either in gen 0 or not at all.
Collect objects in gen 0 or not at all.
Different The thing is, you want an object to have an extremely short lifetime and never touch it during GC, or, if you can't do that, they should go to 2 generations as fast as possible and stay there forever. , will never be recycled. This means that you keep a reference to a long-lived object forever. Usually, it also means that objects can be reused, especially objects in large object heaps.
The collection of each higher generation of GC will be more time-consuming than the previous generation. If you want to keep many generation 0,1 and few generation 2 objects. Even if background GC is turned on to do 2 generations of recycling, it will consume a lot of CPU operations. You may prefer to use this part of the CPU to the application instead of GC.
Note You may have heard the saying that every 10 generation 0 collections will produce a 1 generation collection, and every 10 generation 1 collections will produce a 2 generation collection. This is actually incorrect, but you need to understand that you want to generate as many fast generation 0 collections as possible, and a small number of generation 2 collections.
You'd better avoid generation 1 recycling, mainly because objects that have been promoted from generation 0 to generation 1 will be transferred to generation 2 at this time. Generation 1 is a buffer for objects entering Generation 2.
Ideally, every object you allocate should end its life cycle before the next generation 0 collection. You can measure the time between GCs and compare it to the lifetime of objects in your application. Information on how to use tools to measure life cycles can be found at the end of this chapter.
You may not be used to thinking like this, but this rule cuts into every aspect of the application. You need to think about it often and make a fundamental change in your mentality, so that you can implement this most important rule.
Shorten the life cycle of objects
The shorter the scope of an object, the smaller the chance it will be promoted to the next generation when the next GC occurs. In general, don't create objects until you need them.
At the same time, when the cost of object creation is so high, exceptions can be created earlier so that they will not interfere with other processing logic.
In addition, you must ensure that the object exits the scope as early as possible. For local variables, you can end their lifetime after the last use, or even before the method ends. You can use {} to enclose the code. This will not affect your execution, but the compiler will consider that the object in this scope has completed its life cycle and is no longer used. If you need to call an object's method, try to reduce the time interval between the first and last calls so that the GC can recycle the object as early as possible.
If the object is associated (referenced) with some objects that will be maintained for a long time, you need to release their reference relationships. You may have more null checks, which may make the code more complex. It can also create a tension between the object's available state (always having full state available) and efficiency, especially when debugging.
One solution is to convert the object to be cleared into another way, such as a log message, so that the relevant information can be queried during subsequent debugging.
Another method is to add configurable options to the code (without dissolving the relationship between objects): running the program (or running a specific part of the program, such as a specific request), there is no disassembly of the objects in this mode reference relationship, but to keep the object as convenient as possible for debugging.
Reduce the depth of the object hierarchy
As mentioned at the beginning of this chapter, the GC will traverse along the reference relationship of the object when recycling. In server GC mode, GC will run in a multi-threaded manner, but if a thread needs to process an object at a deep level, all threads that have processed it will need to wait for this thread to complete the processing before exiting. In future CLR versions, you don't need to pay too much attention to this issue. GC will use a better marking algorithm for load balancing during multi-thread execution. But if your object level is very deep, you still need to pay attention to this issue.
Reduce references between objects
This is related to the depth of the previous section, but there are also some other factors.
If an object references many objects (array, List), it will spend a lot of time traversing the objects. It is the GC that causes a problem for a long time because it has a complex relationship graph.
Another problem is that if you cannot easily determine how many reference relationships an object has, then you cannot accurately predict the life cycle of the object. Reducing this complexity is quite necessary, not only to make the code more robust, but also to facilitate debugging and achieve better performance.
In addition, please note that references between objects of different generations will also cause inefficiency of GC, especially references from old objects to new objects. For example, if a 2nd generation object has a reference relationship in a 0th generation object, then every time a generation 0 GC occurs, some of the 2nd generation objects also need to be scanned to see if they still hold references to the 0th generation object. Although this is not a full GC, it is still unnecessary work and you should try to avoid this situation.
Avoid pinning objects (Pinning)
Pinning objects can ensure the safety of data transferred from managed code to local code. Common ones are arrays and strings. If your code doesn't need to interact with native code, don't worry about its performance overhead.
Pinning an object means that the object cannot be moved during garbage collection (compression phase). Although pinning objects does not cause much overhead, it will hinder GC recycling operations and increase the possibility of memory fragmentation. The GC will record the location of objects when recycling so that the space between them can be used when re-allocating. However, if there are many pinned objects, it will lead to an increase in memory fragmentation.
Nails can be explicit or implicit. What is shown is to set it with the GCHandleType.Pinned parameter when using GCHandle, or use the fixed keyword in unsafe mode. The difference between using the fixed keyword and GCHandle is whether the Dispose method will be called explicitly. Although using fixed is very convenient, it cannot be used in asynchronous situations. However, you can still create a handle object (GCHandle) and pass it back and process it during the callback.
Implicitly pinned objects are more common, but they are also more difficult to detect and remove. The most obvious example is passing objects to unmanaged code through platform calls (P/Invoke). This isn't just your code - some of the managed APIs you call frequently actually call native code and pin objects as well.
CLR will also pin some of its own data, but this usually doesn't require you to care.
Ideally, you should try not to pin objects as much as possible. If this is not possible, then follow the previous important rules and try to release these pinned objects as soon as possible. If the object is simply pinned and released, there is not much chance of affecting the collection operation. You also want to avoid pinning multiple objects at the same time. It is slightly better if pinned objects are swapped to generation 2 or allocated in LOH. According to this rule, you can allocate a large buffer on the large object heap and manage the buffer yourself according to actual needs. Or allocate buffers on pairs of small objects and then upgrade them to generation 2 before pinning them. This is better than pinning the object directly to generation 0.
The above is the detailed content of Practical tutorial on writing high-performance .NET. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



The edge browser comes with a translation function that allows users to translate anytime and anywhere, which brings great convenience to users. However, many users say that the built-in translation webpage is missing. Then the edge browser automatically What should I do if the translation page I brought is missing? Let this site introduce how to restore the translated web page that comes with the Edge browser if it is missing. How to restore the translation webpage that comes with the Edge browser is missing 1. Check whether the translation function is enabled: In the Edge browser, click the three dots icon in the upper right corner, and then select the "Settings" option. On the left side of the settings page, select the Language option. Make sure "Translate&rd"

What to do with blue screen code 0x0000001? The blue screen error is a warning mechanism when there is a problem with the computer system or hardware. Code 0x0000001 usually indicates a hardware or driver failure. When users suddenly encounter a blue screen error while using their computer, they may feel panicked and at a loss. Fortunately, most blue screen errors can be troubleshooted and dealt with with a few simple steps. This article will introduce readers to some methods to solve the blue screen error code 0x0000001. First, when encountering a blue screen error, we can try to restart

According to news on July 22, today, the official Weibo of Xiaomi ThePaper OS announced that Xiaoai Translation has been upgraded. Real-time subtitles have been added to Japanese and Korean translations, and subtitle-free videos and live conferences can be transcribed and translated in real time. Face-to-face simultaneous interpretation supports translation into 12 languages, including Chinese, English, Japanese, Korean, Russian, Portuguese, Spanish, Italian, French, German, Indonesian, and Hindi. The above functions currently only support the following three new phones: Xiaomi MIX Fold 4 Xiaomi MIX Flip Redmi K70 Extreme Edition It is reported that in 2021, Xiao Ai’s AI subtitles will be added to Japanese and Korean translations. AI subtitles use Xiaomi’s self-developed simultaneous interpretation technology to provide a faster, more stable and accurate subtitle reading experience. 1. According to the official statement, Xiaoai Translator can not only be used in audio and video venues

Termination Code 0xc000007b While using your computer, you sometimes encounter various problems and error codes. Among them, the termination code is the most disturbing, especially the termination code 0xc000007b. This code indicates that an application cannot start properly, causing inconvenience to the user. First, let’s understand the meaning of termination code 0xc000007b. This code is a Windows operating system error code that usually occurs when a 32-bit application tries to run on a 64-bit operating system. It means it should

If you need to program any device remotely, this article will help you. We will share the top GE universal remote codes for programming any device. What is a GE remote control? GEUniversalRemote is a remote control that can be used to control multiple devices such as smart TVs, LG, Vizio, Sony, Blu-ray, DVD, DVR, Roku, AppleTV, streaming media players and more. GEUniversal remote controls come in various models with different features and functions. GEUniversalRemote can control up to four devices. Top Universal Remote Codes to Program on Any Device GE remotes come with a set of codes that allow them to work with different devices. you may

What does the 0x000000d1 blue screen code mean? In recent years, with the popularization of computers and the rapid development of the Internet, the stability and security issues of the operating system have become increasingly prominent. A common problem is blue screen errors, code 0x000000d1 is one of them. A blue screen error, or "Blue Screen of Death," is a condition that occurs when a computer experiences a severe system failure. When the system cannot recover from the error, the Windows operating system displays a blue screen with the error code on the screen. These error codes

Browsers generally have built-in translation functions, so you don’t have to worry about not being able to understand when browsing foreign language websites! Google Chrome is no exception, but some users find that when they open the translation function of Google Chrome, there is no response or failure. What should they do? You can try the latest solution I found. Operation tutorial: Click the three dots in the upper right corner and click Settings. Click Add Language, add English and Chinese, and make the following settings for them. The English setting asks whether to translate web pages in this language. The Chinese setting displays web pages in this language, and Chinese must be moved to the top before it can be set as the default language. If you open the webpage and no translation option pops up, right-click and select Translate Chinese, OK.

As a programmer, I get excited about tools that simplify the coding experience. With the help of artificial intelligence tools, we can generate demo code and make necessary modifications as per the requirement. The newly introduced Copilot tool in Visual Studio Code allows us to create AI-generated code with natural language chat interactions. By explaining functionality, we can better understand the meaning of existing code. How to use Copilot to generate code? To get started, we first need to get the latest PowerPlatformTools extension. To achieve this, you need to go to the extension page, search for "PowerPlatformTool" and click the Install button
