.NET concept arising from a performance problem
Keywords: .NET Performance GC Value Type Reference Type Stack Stack String
1 group
Let's take a look at the two groups of code. Which code is more efficient in each group?
First group:
Code 1:
For (int i = 0; i <10000; i )
{
AddressData DS = New AddressSData ();
DS = addresss.getaddress ();
}
Code 2:
For (int i = 0; i <10000; i )
{
AddressData DS;
DS = addresss.getaddress ();
}
Second Group:
Code one:
String strnames = "@" guid.newguid (). Tostring (). Replace ("-", "") ", @" guid.newguid (). TOSTRING (). Replace (",", " ) "@" Guid.newguid (). Tostring (). Replace ("-", "");
For (int i = 0; i <10000; i )
{
......
}
Code 2:
For (int i = 0; i <10000; i )
{
String strnames = "@" guid.newguid (). Tostring (). Replace ("-", "") ", @" guid.newguid (). TOSTRING (). Replace (",", " ) "@" Guid.newguid (). Tostring (). Replace ("-", "");
......
}
In each set of code, the functions of the two code implementations are the same, and the differences between them are also small, but their efficiency will be amazing, one of which will be very frequent GC, why?
When answering this question, let's first understand a few .net concepts.
2 What is GC
The full name of GC is Garbage Collection, Chinese name garbage recycling, is a feature of .NET's memory management. The garbage collector tracks and reclaims the object allocated in the hosted memory, regularly performs garbage collection to recover the memory that is not effectively referenced. When the memory request cannot be met using the available memory, the GC will be automatically performed.
At the time of garbage collection, the garbage collector returns to the managed object in memory, and then searches for the referenced object from the managed code and marks as valid, then releases that the memory is not marked as a valid object and retracts the memory. Effective objects move together. This is the four steps of GC.
It can be seen from the above, GC is very influential, so it is generally said that this kind of thing is still as possible.
In order to reduce some performance impact, .NET's GC support object aging, or the concept of independence, the generation is the measurement unit, an algex, or a generation of an algenever, or a period of the object. Currently .NET's garbage collector supports three generations. Each time the GC is performed, there is no recycled object to automatically improve the generation. Copy-created objects belong to a new generation, which is lower than the algebra of objects created earlier in the application lifecycle. The object in the middle of the rare is in zero. When each GC is time, the objects in the zero generation are first reclaimed, and only the more than the demand is still unable to meet the demand after the lower algebraic object recycling is completed. 3 stacks and piles
The memory has the concept of stacks and stacks. The stack follows the principle of the advancement, and the object that is pushed into the stack must implement the pull-out stack, which guarantees the compact of this part of the memory, and basically does not need to consider the memory address. And the stack does not have this principle, and any object may be in the heap at any time, or it may be removed at any time. This is obvious, we should consider where every object is saved, so you need to save each object in the stack to save the address in the heap. At the same time, after a period of time, we will find a lot of gaps in the heap, which is fragments. In order to improve system performance, we often need to organize piles at this time to remove debris. About stacks and piles, as shown below:
4 GC and stack, pile
It can be seen from the concept of the aforementioned stack and heap that there is no garbage collection. It only needs to be directly pressing, and the heap is facing a very complex garbage collection. The GC is completely a heap, and whether it is effective if the object in the heap is achieved by traversing the stack. Here, a reference count is involved, and the reference count is a statistical statistics for the number of objects in the heap, and when the reference count of an object is zero, then this object can be reclaimed. When the GC is performed, the garbage collector traverses the stack. When a stack of addresses, it adds the reference to the object on the number of objects in the stack 1, and then destroy all the reference counts in the heap to zero objects, recover memory And organize the fragments in the heap.
5 value type and reference type
We all know that data types in your computer are divided into value types and reference types. So what is the value type? What is the reference type?
Most programming languages provide built-in data types (such as integers and floating point numbers), which are replicated as parameters (ie, they pass values). In .NET Framework, these are called value types. Running supports two value types: built-in value types, and user-defined value types.
The reference type stores a reference to the value of the memory address. The reference type can be a self-description type, a pointer type, or an interface type. The type of reference type can be determined by the value of the self-description type. The self-description type is further subtracted into array and class types. Class types are user-defined classes, packages, and delegates.
As a variable of value type, each has its own data copy, so the operation of a variable does not affect other variables. As the reference type, variables can be referenced by the same object; therefore, the operation of a variable will affect the same object referenced by another variable.
6-value type, reference type and stack, pile
Understand the value type and reference type, then how does these two types express in memory?
The value type is stored in the stack, and the reference type is stored in the heap, then stores the reference to the object in the stack (also called the pointer) in the stack, as shown below:
Because of such a storage method, there is a different impact on the variable operation, such as changes made by the reference pointer B on the data, are also expressed in the data obtained by reference pointer C. The value of the value is not allowed to have such a situation.
These two differences will also be in our way, for example:
We assume that the modifyclass () method is to add 2 in the class of Classa, Classa CA = New Classa ();
Ca.value1 = 2;
ModifyClass (CA);
INT getValue = ca.value1;
......
At this point you can see the value of getValue is 4, and the modifyclass () method does not return any data.
For value type, we will find that this is not possible, you have to let the method return data, such as:
INT CA = 2
INT getValue = ModifyValue (CA);
The difference between value types and reference types is that when the new variable is declared, if Classa CA = NULL is legal, INT CA = NULL is illegal.
7 instantiated steps
Class is the most common also the most common type of reference, we know that instantiate a class is a statement of our Siki:
Classa ca = new classa ();
So what is the computer did it in this short sentence?
In fact, the computer has roughly doing such a few things in this process:
First, in Classa CA, generate an empty reference pointer and push it into the stack:
Then, when new classa (), generate a new instance of ClassA and put it in a heap:
In assignment number = this step, point the CA's reference pointer to the new instance of just generated:
At this time, the operation of the whole statement was completed.
Ok, after understanding these concepts, we can answer questions started with this article:
8 answering questions starting this article
About the first group of code, we must first understand
AddressData DS = New AddressSData ();
DS = addresss.getaddress ();
In memory, we already know that after the first sentence of the above code is completed, it will look like this:
After the second sentence is completed, it will become such a look:
Example 1 of ClassA is generated by the code code. Example 2 is generated by the addressss.getaddress () method. Instance 2 is an effective object, and instance 1 unfortunately falls a generation. It can only wait for garbage collection. The destiny is recovered.
In general, this approach does not bring too much performance problem, but in some cases? For example, this is the one cycle in this article?
At this time, a lot of garbage will be produced in the heap, which takes up a lot of memory, so you have to constantly GC, thus seriously affecting performance.
So what about the second group of code?
It seems that the second group code and the first group of code are very different, one is a typical reference type of class, and one is something that is characterized by a string like a value type.
In fact, the string is a very special stuff, its characteristics of the type and reference type, such as we must use this way:
String DS = "this is a test";
DS = ModifyString (DS);
It should be noted that the second sentence is the second sentence. This is a typical way to operate. The modifyString () method must return data; but on the other hand, we can write this way when we initialize a new string variable. : String DS = NULL. Very strange, I feel, the reason why this happens may be that the designer wants it as much as possible and other value types such as int, float and other data types, after all, its own characteristics and give Our feelings are so similar, but it is unable to fix the length, int and float, etc. We are clearly defined how much it is, but String is not. For this reason, the performance difference between the second set of two codes is caused.
9 Some questions: Do you have to use Class?
We know that Class is a reference type, and Struct is a value type. Class is unique to object-oriented programming era, and we call Struct is just a variant of an object-oriented phase-oriented phase. So that Java abandoned the concept of Struct, then why didn't it give up what Java gives up?
Struct is not garbage. First, Struct is a value type, which allows it to be stored in the stack, not a heap, that is, it does not bring the performance impact of GC; secondly, 100 elements in an object, if This object defines how many memory spaces that will occupy each of the categories and structures? The answer is that the definition is class up to 101 memory spaces, which are 100 elements and reference pointers, respectively; and the defined structure only takes only 100 pieces. Maybe you will say that there is no relationship with such a piece of such a piece, but add 1%, then, if this object has only three elements?
So we can conclude that Class is not unique.