. Net garbage collection and large object processing memory defragmentation

Source: Internet
Author: User
Tags garbage collection

The CLR garbage collector divides objects according to the size of the space they occupy. Large objects and small objects are handled in a very different way. For example, memory defragmentation-the cost of moving large objects in memory is expensive, let's look at how the garbage collector handles large objects, and what the potential impact of large objects has on program performance.

Large object heap and garbage collection

In. Net 1.0 and 2.0, if an object is larger than 85000byte, it is considered a large object. This number is based on the experience of performance optimization. When an object requests memory size to reach this threshold, it is assigned to the large object heap. What does that mean? To understand this, we need to understand. NET garbage collection mechanism.

As most people know, the. Net GC is recycled by "generation." There are 3 generations, 0 generations, 1 generations and 2 generations in the program, and 0 generations are the youngest objects, and 2 generation objects live the longest. GC Garbage collection is also for performance reasons; The usual objects are recycled in the 0 generation. For example, in a asp.net program, objects associated with each request should be recycled at the end of the request. Objects that are not recycled become 1-generation objects, meaning that the 1-generation object is a buffer between the resident memory object and the immediate extinction object.

From a generational perspective, a large object belongs to a 2-generation object, because large objects are processed only when the 2 generation is recycled. When a generation of garbage collection executes, a more youthful generation of garbage collection is performed concurrently. For example, when the 1 generation garbage collection will be recycled at the same time 1 and 0 generations of objects, when 2 generation garbage collection will perform 1 generation and 0 generation of recycling.

Generation is a logical view of the garbage collector that distinguishes memory regions. From the physical storage point of view, objects are allocated on different managed heaps. A managed heap (managed heap) is the memory area that the garbage collector requests from the operating system (by invoking the Windows API VirtualAlloc). When the CLR loads memory, it initializes two managed heaps, a large object heap (Loh–large object heap), and a small object pair (Soh–small object heap).

The memory allocation request is where the managed object is placed on the corresponding managed heap. If the object is smaller than 85000byte, it will be placed in the SOH, otherwise it will be placed on the Loh.

For Soh, after a garbage collection is performed, the object enters the next generation. That is, if the surviving object enters the second generation at the time of the first garbage collection, if the object is not reclaimed as garbage after the 2nd garbage collection, it becomes a 2 generation object, and the 2 generation object is the oldest object that is not ascending algebra.

When garbage collection is triggered, the garbage collector will defragment the small object heap to move the surviving objects together. For large object heaps, because of the high overhead of mobile memory, the CLR team chooses to just clear them up and make a list of the objects that are recycled, so that the next time a large object application uses memory, the adjacent garbage object is merged into a block of free memory.

Always keep in mind that the large object heap will not be defragmented until. Net 4.0 and may be done in the future. So if you want to assign large objects and don't want them to be moved, you can use the fixed statement.

Example of the next small object heap Soh recycling diagram

There are four objects obj0-3 before the first garbage collection in the figure above, Obj1 and obj3 are reclaimed after the first garbage collection, and Obj2 and Obj0 are moved together; three objects were allocated before the second garbage collection obj4-6 The Obj2 and Obj5 were reclaimed after the second execution of the garbage collection, and Obj4 and Obj6 were moved to the obj0 side.

The figure below is a sketch of the large object heap Loh recovery

You can see a total of four objects obj0-3 before garbage collection has been performed; the first generation of garbage collection after Obj1 and Obj2 were recycled, after recycling obj1 and Obj2 occupied space was merged together, When the OBJ4 application allocates the memory, it assigns the space released by the OBJ1 and Obj2 after the recovery, and leaves a fragment of memory. If the size of this fragment is less than 85000byte, the fragment will never be used again in the lifetime of the program.

If there is not enough free memory on the large object heap to accommodate the large object space to request, the CLR will first attempt to request memory from the operating system, and if the request fails, a second generation of recycling will be triggered to attempt to free some memory.

In the 2 generation of garbage collection, unwanted memory can be returned to the operating system via VirtualFree. The return process is shown in the following figure:

When do you recycle big objects?

Before discussing when to recycle large objects, let's look at the timing of common garbage collection operations. Garbage collection occurs under the following conditions:

1. Applications for more than 0 generations of memory size or large object heap thresholds, most of the managed heap garbage collection occurs in this case

2. When calling the Gc.collect method in program code, if the Gc.collect method is invoked to pass in the Gc.maxgeneration parameter, garbage collection for all generations of objects, including garbage collection of the large object heap, is performed

3. When the application receives a high memory notification from the operating system when the operating system is out of memory

4. If the garbage collection algorithm believes that the second generation of recycling is effective, will trigger the second generation of garbage collection

5. Each generation of object heap has an attribute of the size of the valve value of the space, when you assign an object to a generation, you increase the amount of memory close to the threshold of the generation, or allocate objects that cause this generation's heap size to exceed the heap thresholds, a garbage collection occurs. So when you assign a small object or a large object, it corresponds to the threshold that consumes the 0 generation heap or the large object heap. When the garbage collector promotes object algebra to 1 generation or 2 generations, it consumes 1, 2-generation thresholds. These thresholds are dynamically changing during program operation.

Performance impact of large object heap

Let's look at the cost of allocating large objects first. When the CLR allocates memory for each new object, it ensures that the memory is emptied and is not used by other objects (I give out are cleared). This means that the cost of the allocation is completely clearing (unless a garbage collection is triggered at the time of allocation). If it takes 2 cycles to clear the 1byte (cycles), it means that it takes 170,000 cycles to clean up one of the smallest large objects. Typically, people don't allocate oversized objects, such as allocating 16M objects on a 2GHz machine, and approximately 16ms to empty the memory. The price is too great.

Let's look at the cost of recycling. As mentioned earlier, large objects and 2-generation age objects are recycled together. If a large object or a 2-generation object occupies more space than its threshold, it triggers a collection of 2-generation objects. If the 2 generation collection is triggered by exceeding the threshold of the large object heap, the 2 generation object heap itself does not have many objects that can be recycled. If there are not many objects on the 2 generation heap, this is not a big problem. But if the 2 generation heap has a large number of objects, too many 2 generations of recycling can cause performance problems. If you are assigning large objects on a temporary basis, you will need a lot of time to run garbage collection, which means that if you continue to use large objects and then release large objects, it can have a significant negative impact on performance.

The huge objects on the large object heap are usually arrays (rarely one object is large). If an element in an object is a strong reference, the price is high, and if there is no reference between the elements, garbage collection does not need to traverse the entire array. For example, an array is used to hold the nodes of a binary tree, one way is to strongly reference the left and right nodes in a node:

Class Node

{

Data D;

Node left;

Node right;

}

node[] BinaryTree = new Node[num_nodes];

If Num_nodes is a large number, it means that each node needs to see at least two reference elements. An alternative is to save the array index number of the left and right node elements in the node

Class Node

{

Data D;

UINT Left_index;

UINT Right_index;

}

In this case, the reference relationship between the elements is removed; You can get the referenced node by Binarytree[left_index]. The garbage collector does not need to look at the relevant reference elements when doing garbage collection.

Collecting performance data for a large object heap

There are several ways to collect performance data related to a large object heap. Before I explain these methods, let's talk about why we need to collect the performance data associated with the large object heap.

When you start to collect performance data for some aspect, it is possible that you have found evidence of a performance bottleneck in this area, or that you have not looked at all aspects of the problem.

When looking for performance issues. Net CLR Memory Performance counters are usually the tools that should be considered first. The counters associated with Loh are Generation 2 collectioins (2 Generation heap collection) and large object heap size large Object heap sizes. Generation 2 Collections shows the number of garbage collection operations that occurred 2 generations after the process started. The Large object Heap size counter displays the value of the current large object heap, including the free space, which is updated after each garbage collection operation, not every time the memory is allocated.

You can refer to the following figure to observe the. Net CLR memory related performance data in Windows performance counters

You can also query the values of these counters by program, and many people collect performance counters by program to help find performance bottlenecks.

Of course, you can also use the debugger winddbg to observe the large object heap.

The last hint: so far, the large object heap as part of garbage collection is not done in memory defragmentation, but this is a CLR implementation details, the program code should not rely on this feature. If you want to make sure that the object is not moved by the garbage collector, use the fixed statement.

Article Source: Bole Online

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.