It turned out to be like this: What happened to a new object in C?

Source: Internet
Author: User

Q: What will happen when we create an object?
A: call this type of constructor.

The problem seems simple, but in fact, CLR does more than that...
To answer this question accurately, we need to explain it in detail.

A new reference type
First, to instantiate a reference type, you must allocate memory on the stack. To allocate memory, you need to calculate how much space the reference type occupies and how much memory is allocated to it.
How can we calculate it? Simple! You only need to calculate the total length of all fields of this type. We know that fields of the reference type occupy the length of a pointer (4 bytes on 32-bit machines and 8 bytes on 64-bit machines ). The length of a field of the value type can be calculated using a recursive method (the recursive end point is a reference type or a basic type ). Based on this information, we can easily calculate the total length of all fields.
But in fact, the calculation method will be a little more complicated than this, because we have to consider the memory alignment. I have attached the explanation of the memory alignment to the end of this article, so I won't say much here. After memory alignment is considered, the result may be slightly larger than the previous one.
However, this is still not the final result. To get the final result, you also need to add the length of two pointers. The reason is that each object allocated to the heap has two "extra overhead" of pointers, which are synchronized block indexes and type pointers. One or two statements about synchronizing block indexes are not clear, but you can simply understand it as a pointer pointing to a "synchronous block, this "synchronization block" is used to enable the objects with the synchronization block to support thread synchronization. The so-called type pointer can be understood as follows: each object is a type instance, and each type itself has a type instance to represent, the object type pointer is the pointer to the type instance of this type. For example, we know that the value of typeof (string) is a type instance, this type instance is what all the string object type pointers point.
So far, we can get the number of memories that need to be allocated to instantiate a reference type. However, it should be noted that the CLR does not calculate the size of allocated memory at runtime, but has already calculated this amount as early as compilation.
The next step is to initialize the allocated memory block. This is simple. You only need to set all the binary bits in the memory to 0.
Then, two "additional overhead" values are initialized. For synchronous block indexes, CLR initializes them into a negative number and does not point to any synchronization block. This is because we do not require most objects to support thread synchronization, so we don't have to rush to instantiate a synchronization block for them and allocate it when it is really necessary. For a type pointer, it points to a real object, that is, the type object instance of this type.
Then, the constructor of the call type is called.
After completing the above steps, an object instance of the reference type is ready, and the new operator only needs to return the reference of this instance to complete the task.

New Value Type
First, we need to calculate the amount of memory to be allocated. Because the value type does not have the so-called "additional overhead", the memory length required for the value type is the total size of its internal fields (also need to consider memory alignment ). Similarly, the CLR has already computed this amount during compilation and does not need to be computed at runtime.
Then, the CLR allocates the required memory. Where is the allocation? This is not true. It is possible to stack or stack.
Then we call the Type constructor. Note that the CLR does not initialize the memory block. Instead, it submits all tasks for initializing the memory block to the constructor. This is to ensure that the value type is lightweight. This is also why the C # language requires a value assignment in the Value Type constructor. In addition, all Default constructors of the Value Type initialize the internal fields to 0.
At this point, a value type is also ready. Generally, for value types, the new operator does not need to return its address. The reason is that the position of value types is relatively fixed, so they can be basically determined during compilation. For example, each value type instance on the function Stack has an offset relative to the stack, which is determined during compilation. For example, the value type of a field of the reference type has an offset relative to the address of the reference type, which is fixed as early as compilation. Therefore, the new operator does not need to return the address of the type instance.

Now we know what the CLR needs to do for every new object. It can be seen that CLR tasks are not easy. It would be harder for CLR to take into account the garbage collection of a new object. Therefore, every time we want to instantiate a type, we have to think twice...

 

Appendix: Memory alignment(This is my previous study note. I don't remember it very systematically. If you are interested, just take a look ...)

Why is memory alignment required?

To improve program performance, data structures in the memory should be aligned on the natural boundary as much as possible. The reason is that in order to access non-alignment memory, the processor needs to perform two memory accesses, while alignment memory access only needs one access. (For words, double words, and four words, the natural boundary is an even number of addresses, which can be divided by four, and an address that can be divided by eight .)

How is memory used for it?

A single-or dual-character operand spans the 4-byte boundary, or a four-character operand spans the 8-byte boundary, which is considered not aligned and thus requires two bus cycles to access the memory. The starting address of a word is odd, but it does not span the word boundary. It is considered to be aligned and can be accessed in a bus cycle.

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.