Stack, heap, value type, reference type part (2)

Source: Internet
Author: User

In Part 1, we briefly introduced the functions of the stack, the value type, the storage location of the reference type in the stack, and the pointer is Xiami. Let's continue at the pace of the revolution!

Parameters, the big picture.

During code execution, what are the underlying insider transactions? When we call a method:

  • The stack top allocation control is used to store information contained in the execution of our method. This part of space is called a stack frame. For details, see the floor appendix ). There is a pointer in the header pointing to the call address. This is usually a goto command, so that after the thread executes our method, it will know where to continue executing the stuff in the next stack. (Delete the stack frame)
  • The parameters of the method are completely copied. This part will be explained in detail.
  • Control is handed over to the JIT compiled method instruction set to start real code execution. In fact, there is another method in the call stack, which exists in the stack box. (See Appendix)

The Code comes again:

Public int addfive (INT pvalue) {int result; Result = pvalue + 5; return result ;}

 

At this time, our stack looks like this sauce:

As mentioned above, if the parameter is of the value type, the content will be completely copied. If it is a reference type, the copied pointer is only a pointer to the instance in the heap.

Passing value types.

First, when we pass a value type, the stack top allocates space of the corresponding size and copies the value completely. For example:

Class class1 {public void go () {int x = 5; addfive (x); console. writeline (X. tostring ();} public int addfive (INT pvalue) {pvalue + = 5; return pvalue ;}}

When the method is executed, X is allocated space and value 5 is assigned to the allocated space.

Next, addfive is pressed to the stack, and its parameters are also pressed to the stack (space allocation). Then, the parameter values are copied from X, one byte to one byte.

When the addfive execution ends, the thread returns to the Go method. Because addfive has no utilization value, its parameter pvalue is useless. "delete it ".

So the output of our code should be 5, right? The key point is that any value type transmitted in this way is a copy of it, and we want the values in the original variables to remain unchanged.

But remember, if our value type is quite large (occupying space), such as a large struct, it will take a lot of time to copy it. At the same time, the stack space is not infinitely large, just like the water from the tap of the bottle, it will always overflow! Struct may often become very large, so be careful when using it. How big is it? This is big, big, struct ...... * (* & @ # ¥ % ):

Public struct mystruct {long A, B, C, D, E, F, G, H, I, J, K, L, M ;}

Check whether the Xiami occurs when this struct is used:

Public void go () {mystruct x = new mystruct (); dosomething (x);} public void dosomething (mystruct pvalue) {// do something here ....}

This is really inefficient. Imagine how terrible it would be if there were thousands of calls to this struct!

What can we do? Is my program used thousands of times? The answer is to pass a reference to this value type rather than the value type itself:

Public void go () {mystruct x = new mystruct (); dosomething (ref X);} public struct mystruct {long A, B, C, D, E, F, G, h, I, J, K, L, M;} public void dosomething (ref mystruct pvalue) {// do something here ....}

In this way, we can avoid inefficient memory allocation.

Now we need to be careful with the problem. If we use the reference to pass the parameter, we will operate on the value in the original value type. That is to say, if we change the value of pvalue, then X also changes. Let's look at the following code. The result we get is 12345, because pvalue actually points to the content of X.

Public void go () {mystruct x = new mystruct (); X. A = 5; dosomething (ref X); console. writeline (X. a. tostring ();} public void dosomething (ref mystruct pvalue) {pvalue. A = 12345 ;}

Passing reference types.

The transfer of the reference type and the use of the reference to pass the value type are basically not much difference.

If we use the value type in it:

Public class Myint {public int myvalue ;}

And call the go method. Myint exists on the stack because it is a reference type:

Public void go () {Myint x = new Myint ();}

If we change the go method:

Public void go () {Myint x = new Myint (); X. myvalue = 2; dosomething (x); console. writeline (X. myvalue. tostring ();} public void dosomething (Myint pvalue) {pvalue. myvalue = 12345 ;}

The situation is as follows:

  1. Variable X pressure stack when calling go
  2. Pvalue pressure stack when dosomething is called
  3. The value of X (the address of Myint in the stack) is copied to pvalue.

In this way, we can explain why when we change the value type myvalue of the reference type attribute, the result is 12345 after the change.

Interestingly, what happens when we use a reference to pass a reference type?

Try it. Assume that the following reference types exist:

Public class thing {} public class animal: thing {public int weight;} public class vegetable: thing {public int length ;}

The Go method is defined as follows:

Public void go () {thing x = new animal (); switcharoo (ref X); console. writeline ("X is animal:" + (X is animal ). tostring (); console. writeline ("X is vegetable:" + (X is vegetable ). tostring ();} public void switcharoo (ref thing pvalue) {pvalue = new vegetable ();}

The result variable X is changed to vegetable.

X is animal: false

X is vegetable: True

Let's see what's going on:

  1. Start to execute the go method. At this time, the X pointer exists in the stack.
  2. Animal exists in heap
  3. Run the switcharoo method. pvalue exists in the stack and points to X (reference transfer)

  1. Vegetable allocation in heap (new vegetable)
  2. Pvalue points to X, so changing the content of pvalue actually changes the content pointed to by X. Therefore, the effect of receiving pvalue by X points to vegetable.

If we do not pass through the reference, we will get the opposite result, and X is still animal. (Why? You can draw a picture by yourself)

In conclusion

In the following sections, we will introduce how variables are referenced in the stack, and how to overcome some troubles when copying objects.

Appendix

Here there are two concepts, one is call stack, the other is stack frame, in Wikipedia has a detailed explanation, I will be free to translate again, now you can read the original article: http://en.wikipedia.org/wiki/Call_stack

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.