Bastard Detail C #: A value type that is not a "stack type", stored from the life cycle chat location

Source: Internet
Author: User

0x00 Preface:

Bastard when communicating with others on a daily basis, it is often found that once the discussion involves "type", the heat of the topic heats up immediately, because many specious, or one-sided concepts are often regarded as comprehensive and correct answers. In addition to the recent "C # heap vs Stack" series seen in the garden, it is also interesting, very good, so bastard today also want to talk about the value type from the storage location point of view, but also want to refute the simple "value stack type" theory (its own name, refers to simply the value type as allocated on the stack type).

0x01 Heap vs Stack?

Many crossing think about the allocation of storage space, often think of a thing called memory, of course, if the knowledge of more reliable friends can further know that there are so-called heap and stack concept. Yes, heaps and stacks should be a matter of memory when we first think about the space. But is there anything missing? There are indeed omissions if you do not take into account the register . Here Bastard first put the register, is for the following end of the Echo, about the register of the topic first press the Not table. That threw away the registers and went back to the topic of stacks and stacks that seemed familiar to us. Let's talk about it separately.

Heap

In fact, I prefer to call it a managed heap , but for the sake of simplicity, bastard still uses heaps instead (to understand that the managed heap and heap are not a thing). Why did you talk about the heap first? Because the next chat to the stack you will find that they have a lot of similarities, but the stack to do more attention. There are many details of the implementation of the heap (such as GC), so cop, let's talk about its design ideas without thinking about how it achieves specifics.

Suppose we have a large chunk of memory to prepare for referencing the instance of the type. At the same time, because the possible instances are still "alive", in other words it is still somewhere in this memory, but some instances are dead, in other words, the memory of this instance has been freed, so this block of memory with "whether there are instances of reference types" as the standard, is discontinuous, or there are many "holes". And these "holes" are the spaces we can use to allocate new instances.

So one idea is to build a list of these discontinuous "holes", but each time you allocate space, it's time to check the list to find the right "hole", which is obviously an extra overhead (so pass it off).

So, we obviously prefer to store the memory with the class instance together, with the free memory together (the top). Only in this premise, we can be assured that the new class instance allocation of storage space, and memory allocation implementation is also very easy, easy to what extent? You only need a pointer to move it to achieve the allocation of memory.

To achieve this, we have introduced our often-said GC. (Note: Of course, to specifically talk about GC, may need to consult more information and write more space, and may be more uninteresting, so here bastard is simply introduced, if there are errors, you are welcome to point out. )

The GC's behavioral process can be divided into three stages, which you may also be familiar with:

    1. Marking phase: All instances of the heap are assumed to be "dead" by default, but the CLR clearly knows which instances are alive so that the live instances are marked alive at the beginning of the GC.
    2. Cleanup phase: No marked instances free up space
    3. Compression phase: The heap is re-organized so that the space that holds the live instances of the class is joined together and the free space that has been freed is linked together.

Of course, the cost of GC is still relatively large, so in order to treat the case differently, in order to improve efficiency, GC also has a "generation" concept. Simply put, the instances are grouped into different parts according to their survival time. The purpose is to have different frequency of execution for different survival times.

So you can see that the heap overhead is largely due to the existence of a GC, and the existence of the GC itself is intended to make it easier for the heap to allocate new space.

Stack

Stacks are like heaps, assuming you also have a space for storing data. So what qualifications do we need to add to distinguish heaps from stacks?

Remember what Bastard said when we introduced the heap? "We obviously prefer to store the memory with the class instance together, with the free memory together (top)." The stack is the stack, because the stack at the bottom of the data will always be more than the top data live longer, that is, the stack of space is orderly. The data at the top always dies before the bottom of the data, and because of this, there is no "hole" in the heap in the stack, and the continuous storage space means that we do not need a GC to compress the space. (Image from Network)

It is also because we always know that the top of the stack is empty, and that the top of the stack is the surviving data, so when we allocate new data, we just need to move the pointer. Think of anything? Well, the stack does not need a GC to achieve the best form of allocating new space as the heap pursues.

What good is there? Yes, we also just need to move the pointer to reallocate the stack space. Because it's all just pointer movement, it's less time than using a GC heap (GC markup, cleanup, compression, and the introduction of generational concepts).

So, if you only consider allocating storage space on memory, the heap and stack are actually very similar. The difference is mainly in the cost of GC.

0x02 who "can" use stacks?

Obviously, using stacks is more efficient than using heaps. But why not just use stacks? Because Bastard said before, the stack is the reason for the stack, because the stack at the bottom of the data is always more than the top of the data live longer, only to ensure that the condition, we can use the stack.

So who can guarantee it? Before answering this question, bastard a new question first.

The third form of the variable

If Bastard asks you, are there several forms of variables in C #? You must not escape. is an instance of a value type, an instance of a reference type.

But have you found a problem? Do you really directly manipulate instances of reference types?

Why do you ask?

First, ask a question:

New TypeA ();

What's a in here?

First, it is not an instance of a value type.

Second, look at a bit like an example of TypeA?

Wrong, you can say that it points to an instance of TypeA, but not that it is an instance of TypeA.

Yes, it is a quote that we often say but often ignore. We all manipulate instances of a reference type by reference to the instance.

So, there are three types of variables:

    1. Instances of value types
    2. Instances of reference types
    3. Reference

But here's a very interesting question. As we all know, the spatial allocation of instances of reference types is on the heap. But how does the space for a in the example above be allocated? It is a reference, not an instance of a reference type. Its value points to a block of reference type instances that are allocated on the heap. But doesn't it need storage space itself?

So we should make it clear that all variables will be allocated to the corresponding storage space. Instead, the referenced content points to another piece of storage space.

The life cycle of space

Now that bastard has raised a question, let me ask you one more question. Since the so-called Life time or life cycle is mentioned above, how should the "life cycle of space" be defined?

Then bastard the next definition: the life cycle of a storage space refers to the validity period of the content in this space.

The life cycle is there, but it's clear that a benchmark is needed as a yardstick for measuring the length of the life cycle?

We know that methods are a form of representation of process abstraction. Therefore, we define a term "activity cycle" that is the standard of the method execution time: The time it takes for the method to start executing to a normal return or throw an exception.

And in this method the method body of the variable, obviously want to get its corresponding storage space. If a variable requires more space than the active period of the method, it is marked as a "long life" space , or "lived" space .

The strategy of spatial allocation of m$

OK, Answer bastard above the 2 questions mentioned above, combined with the above bastard mentioned storage space type, we look at the processing of Microsoft .

    1. Three types of storage: stack, heap, register
    2. "Longevity" space is always a heap of space.
    3. The "lived" space is always the stack space or register.
    4. If the runtime is difficult to determine whether the required storage space is "longevity" or "lived", in order to avoid errors, all as "longevity" space processing. For example, an instance of a reference type (not the reference itself) requires space that is always considered "longevity". So the reference type instance is allocated on the heap.
0X03 Conclusion

OK, after reading the Microsoft processing method, bastard again to you to summarize, incidentally answer the 0x02 section title of the problem.

First, we can see that there is no essential difference between a value type instance and a reference (not a reference type instance) on the issue of spatial allocation. That is, they can be allocated on stacks, registers , and heaps, regardless of their type , and only about the life cycle of the space they need is "longevity" or "lived".

Second, one day in a technical group, someone asked how the value type instances in the LAMDA expression should be assigned. Here Bastard also answer this question, the element in the array, the field of the reference type, the local variable in the iterator block, the local variable in the anonymous function (LAMDA) need a space life cycle that is longer than the activity period of the method, even if it is shorter than the method's activity period, but because of the 4th , which is difficult to judge the life cycle of the runtime, ancient capital according to "longevity" space meter. so it's going to be allocated to the heap .

Finally, answer the questions in the topic of this section. Who can use stacks anyway?

In fact, the above has been answered, but here Bastard still give an example to answer it: The value type in the general method local variables or temporary variables.

The reasons are as follows:

    1. The life cycle conforms to the data stored at the bottom of the stack, which is always longer than the top data.
    2. The value of a value type instance is itself, so where they are stored is where they are located. No references are directed to them.
    3. With 2, because the value of an instance of a value type is its own, it does not refer to others without having to relate the life cycle of the referenced instance.
    4. In the final analysis, is it related to the longevity or lived of its space life cycle?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Code word is not easy. Ask for a recommendation

Bastard Detail C #: A value type that is not a "stack type", stored from the life cycle chat location

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.