Http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory2B01142006125918PM/csharp_memory2B.aspx:
2009/12/4
Am-Am reading part of the article is a little slow, but I understand it. Kingsoft is indeed a good thing, ''' ^_^
-- (Part 2) saved 20 minutes and sweated! In fact, the speed is improved, mainly because people are tired and easy to be distracted.
This chapter is too classic. I have a feeling of translating this article, ^_^
-- (Part 3) saved 35 minutes, good, and improved! However, I just understood it, but I still need to look at it carefully. I suddenly felt that
It is difficult to translate this article. ''' think you should take a look at the Chinese "Deep copy" Materials ''''
-- (Part 3) I read it again and thought it could be written.
12/5
Am-Am (part 4) Part 4 I think I should not translate the first three.
At, I suddenly found that there was an article for translating this article on the Internet. After reading English, I found it.
Again, I would like to thank the author for writing such a good article and those who have translated this article.
Due to the trouble of sorting out, I put 1st 2 3 4 parts in word: Download
Although we do not need to worry about memory management and garbage collection in. NET Framework, we should still understand them to optimize our applications. At the same time, we also need to have some basic knowledge of memory management mechanisms, which can help to explain the behavior of variables in our daily program writing. In this article, I will explain the basic knowledge of stacks and stacks, the types of variables, and why some variables can work in their own way.
In the. NET Framework environment, when code is executed, there are two places in the memory to store the code. If you do not know, let me introduce stack and heap to you ). Stack and heap are used to help us run code. They reside in the machine memory and contain the information required for all code execution.
* Stack vs Stack: What is the difference?
Stack is responsible for saving our code execution (or call) path, while stack is responsible for saving the object (or data, next we will talk about a lot of heap problems) path.
Think of stacks as a pile of boxes stacked from top to bottom. Every time we call a method, we record what happens in the application in a box at the top of the stack, and each time we can only use the box at the top of the stack. When the box at the top of the stack is used up or the method is executed, we will leave the box and continue to use the new box at the top of the stack. The working principle of the heap is similar, but most of the time the heap is used to save information rather than save the execution path. Therefore, the heap can be accessed at any time. Compared with the stack, there is no access restriction on the stack. the stack is like the old clothes on the bed. We didn't take the time to sort it out, because we can find the clothes we need at any time, stack is like a shoe box stacked in a locker. We can only take it from the top-level box until we find that it is suitable.
It is not a real representation in the memory, but it can help us distinguish stack and heap.
Stack is self-maintained, that is, the memory automatically maintains the stack. When the box at the top of the stack is no longer used, it will be thrown out. On the contrary, garbage collection needs to be considered for the heap. Garbage collection is used to keep the heap clean. No one wants to see the clothes around it. It's so bad!
* What are the stacks and stacks?
During code execution, four types of data are stored in the stack and stack: Value Type, reference type, pointer ), command (instruction ).
1. Value Type:
In C #, all things declared as the following types are called value types:
- Bool
- Byte
- Char
- Decimal
- Double
- Enum
- Float
- Int
- Long
- Sbyte
- Short
- Struct
- Uint
- Ulong
- Ushort
2. Reference Type:
All things declared as the following types are called reference types:
- Class
- Interface
- Delegate
- Object
- String
3. pointer:
In the memory management solution, the third type is type reference, and the reference is usually a pointer. Pointers are not displayed. They are managed by the Common Language Runtime (CLR. A pointer (or reference) is different from a reference type because when we say that a thing is a reference type, it means that we access it through a pointer. A pointer is a piece of memory space, and it points to another memory space. Just like the stack and heap, the pointer also occupies the memory space, but its value is a memory address or is empty.
4. commands:
In the subsequent articles, you will see how commands work...
* How do I decide where to put it?
Here is a golden rule:
1. The reference type is always in the heap. (Simple enough ?)
2. value types and pointers are always placed in the places where they are declared. (This is a little complicated. You need to know how the stack works before you can determine where the stack is declared .)
As we mentioned earlier, stack is responsible for saving the path for code execution (or calling. When our code starts to call a method, it places an encoding instruction (in the method) on the stack, followed by the method parameters, then, the code is executed to the variable position from the method "Pressure stack" to the top of the stack. The following example makes it easy to understand...
The following is a method ):
public int AddFive(int pValue)
{
int result;
result = pValue + 5;
return result;
}
Now let's take a look at what happened at the top of the stack. Remember that the top of the stack we observe has been pushed into many other contents.
First, the method (only contains the logical bytes to be executed, that is, the command to execute this method, rather than the data in the method body) is imported into the stack, followed by the parameters of the method into the stack. (We will discuss more parameter transfer later)
Then, the control (that is, the thread of the execution method) is passed to the addfive () Instruction in the stack,
When the method is executed, we need to allocate some memory for the "result" variable on the stack,
The method finishes execution and our result is returned.
Method execution is complete, and the result of the method is returned.
By pointing the stack pointer to the available memory address used by the addfive () method, all the memory used by this method on the stack is cleared, and the program will automatically return to the position of the initial method call on the stack (not seen in this example ).
In this example, our "result" variable is placed on the stack. In fact, when the value type data is declared in the method body, they are all placed on the stack.
Value Type data is sometimes stored on the stack. Remember this rule-value types are always placed in the places where they are declared. Okay. If a value type data is declared in the method in vitro and exists in a reference type, it will be replaced by the reference type in the heap.
Let's look at another example:
Suppose we have such a Myint class (it is a reference type because it is a class type ):
Public class Myint
{
Public int myvalue;
}
Then, execute the following method:
Public Myint addfive (INT pvalue)
{
Myint result = new Myint ();
Result. myvalue = pvalue + 5;
Return result;
}
As mentioned above, the parameters of methods and methods are placed on the stack. Next, the control is passed to the addfive () Instruction in the stack.
Then there will be some interesting phenomena...
Because "Myint" is a reference type, it will be placed on the stack, and a pointer reference pointing to the stack will be generated on the stack.
After the addfive () method is executed, we will clear it...
We will keep the remaining lonely Myint objects in the heap (no pointer pointing to the Myint object will exist in the stack !)
This is where the Garbage Collector (GC) works. GC starts to work when our program reaches a specific memory threshold and we need more heap space. GC stops all running threads, finds all objects in the heap that are no longer accessed by the main program, and deletes them. GC then organizes all the remaining objects in the heap to save space, and adjusts all the pointers related to these objects in the stack and heap. You will surely think that this process is very performance-consuming, so you will know why we need to pay so much attention to the stack and stack, especially when writing high-performance code.
OK... This is great. How does it affect me?
Good question.
When we use a reference type, we are actually processing the type pointer, not the type itself. When we use the value type, we are using the value type itself. Sounds confused, right?
The example is the best description.
Assume that we execute the following methods:
Public int returnvalue ()
{
Int x = new int ();
X = 3;
Int y = new int ();
Y = X;
Y = 4;
Return X;
}
We will get the value 3, which is very simple, right?
Assume that we first use the Myint class
Public class Myint
{
Public int myvalue;
}
Then, execute the following method:
What will we get ?... 4!
Why ?... How does X. myvalue become 4 ?... Let's look at what we have done and then we know what is going on:
In the first example, everything is as planned: Public int returnvalue ()
{
Int x = 3;
Int y = X;
Y = 4;
Return X;
}
In the second example, we do not get "3" because the variables "x" and "y" both point to the same object in the heap.
Public int returnvalue2 ()
{
Myint X;
X. myvalue = 3;
Myint y;
Y = X;
Y. myvalue = 4;
Return X. myvalue;
}
We hope that the above content will give you a better understanding of the basic differences between the value type and the reference type in C #, and have a basic understanding of when pointers and pointers are used. In the next part of the series, we will go deep into memory management and discuss the method parameters.