Problem
I recently discussed with my colleagues about the definition of variables in a for loop. First readCode:
Private VoidForinner (){For(IntI = 0; I <5; I ++) {var OBJ =NewMyclass (); console. writeline (obj. Name );}}
This is the code we normally get used to writing. Colleagues mean that if we write it as shown above because every loop occurs, the OBJ variable will allocate a space on the stack, resulting in waste. The OBJ definition should be taken out of the for code block so that less memory can be allocated to improve efficiency. The Code is as follows:
private void forouter () {myclass OBJ; for ( int I = 0; I <5; I ++) {OBJ = New myclass (); console. writeline (obj. name) ;}}
From a normal point of view, writing the variable obj is indeed less memory allocated than above, because obj is defined only once and only allocated once on the stack, used to save the address of the Instance pointing to myclass. To understand this problem, you must first have an understanding of. Net memory allocation. A few tips:
An object of the reference type is created in the following steps:
1. myclass OBJ; create an OBJ variable on the thread stack to save the address of the Instance Object.
2.NewMyclass (); Create an instance object for myclass on the managed stack.
3. The "=" operator symbol OBJ stores the address of the Instance Object.
References:
Anytao masterpiece: http://www.cnblogs.com/anytao/archive/2007/12/07/must_net_19.html
Well, with this background knowledge, it is not difficult to understand why colleagues say that the second write method will allocate less memory. For the first write method, the variable obj is created multiple times, and the second one is only used once. So is it true?
Answer
To find out this problem, we only need to use Il to check the Il of the two codes.
Looking at the two pieces of IL code, we can easily find that no matter which method, the generated Il is almost the same. The difference is thatLocals initThe order of initialization variables varies. For the first method, il does not declare the OBJ variable every time in the loop body.Therefore, these two methods are essentially the same.However, I recommend the first method to define variables directly in the loop body. Because the objects instantiated in the loop body are usually recycled after the loop is completed, or can be referenced by other business objects, such as put in a list. However, the OBJ variable in the second writing method must maintain the object created in the last loop. The release of this object will be restricted, and later newcomers may misoperate this variable when taking over your code, resulting in unnecessary bugs.
Doubt
After this check on IL, I also found a problem. Have you initialized all the local variables of the method in Il at the top of the method body? So I did another test:
Private Void Foreach (){Int Z = 1; var A = New Myclass (); var B = New Myclass (); var c = New Myclass (); var d = New Myclass (); var E = New Myclass (); var F = New Myclass (); var G = New Myclass (); If (Z = 1) Return ; Var H = New Myclass (); var I = New Myclass (); var J = New Myclass (); var K = New Myclass (); var L = New Myclass (); var n = New Myclass (); Return ;}
I have defined many variables in the method. Check whether all the Il files are initialized once. The result is as follows:
As expected, il initialized all the variables at the beginning. In this way, I can't figure it out. If a conditional statement is in the middle of the Code to control return, the variables in the future may not be used, but can't be initialized. Isn't it a rare waste of memory space? I still have a wrong understanding of. locas init!
Confuse
@Temporary variables in the method are allocated on the stack when they enter the method. Variable Allocation and collection are achieved through moving the stack top pointer, which is highly efficient, there is indeed a waste of memory, which is why we recommend writing small methods.
I thought it should be the best answer ~