C # Memory Management for value and reference types

Source: Internet
Author: User

In this log, we will focus on how to improve the performance of software development. This is a deep problem in the software development or development process. This article mainly describes how computing works in the software coding process from two aspects: Memory Allocation and memory recovery. Here you can understand the process and method of memory management, so that you can pay attention to it and use it in future software development.

Value TypeIncluding: int, float, double, bool, structure, reference, representing the variable of the object instance

Reference TypeIncluding: classes and arrays; special reference types: string and Object

Generally, the value type is stored in the stack (excluding the value type included in the reference, such as the value field of the class and the reference field in the class, array elements are stored in the controlled heap with reference); the reference type is stored in the controlled heap. Why is it a controlled heap.

Concepts:

Virtual Memory: 32-bit computer. Each process has 4 GB virtual memory.

Controlled heap (managed heap): who controls it? Of course, it is a useless unit collector, that is, a garbage collector. How to manage it?

Useless unit COLLECTOR: In addition to compressing the managed heap, updating the reference address, and maintaining the list of managed heap information.

The following code is used to store value types:

{

Int age = 20;

Double salesary = 2000;

}

The two variables defined above, int age, tell the compiler to allocate 4 bytes of memory space to store the age value, which is stored on the stack. A stack is a data structure that comes in and out. A stack stores data from a high address to a low address. The computer register holds a stack pointer, which always points to the free space address at the bottom of the stack. When we define an int value, the stack pointer decreases by four bytes; when a variable is out of scope, the stack pointer increments the address of four bytes accordingly. It only moves the stack pointer up and down, so the stack performance is quite high.

Let's take a look at the storage of the reference type and check the code first:

{

Customer customera;

Customera = new customer (); // assume that the customer instance occupies 32 bytes

}

The first line of the above Code first declares a customer reference, the referenced name is mermera, And the bucket is allocated to this reference on the stack. The bucket size is 4 bytes, because it only stores one reference, this reference points to the address of the space to be stored for the customer instance. Note that customera does not point to the specific space at this time, but it only allocates a space.

The second line is being executed ,. NET environment will search for the managed heap, find the first unused, continuous 32-byte space allocated to the class instance, set customera to point to the top position of the Space (the heap space is used from low to high ). When the referenced variable is out of scope, the reference in the stack will be invalid. When the instance in the managed heap is still there, it will be cleared by the garbage collector.

Readers may have some questions as to whether the computer needs to search the entire heap and find enough memory space to store objects when defining the reference type? Will this be very inefficient? What if there is not enough continuous space? We need to talk about "hosting. The heap is managed by the garbage collector ,.. NET releases all objects that can be released when the garbage collector is executed, compresses other objects, and then combines all free space together to move to the top of the heap to Form Continuous blocks, update the reference of other mobile objects at the same time. If you have another object definition, you can quickly find the right space. In this case, the managed heap works in a similar way as the stack. It allocates and recycles space through the heap pointer.

I talked about the management process and method of. Net memory space allocation. Next I will talk about the memory recovery process. When talking about resource cleanup, we have to mention two concepts and three methods.

Two concepts are: managed resources and unmanaged resources.

Managed resources are managed by the CLR (runtime in the general language) of the. NET Framework. Unmanaged resources are not managed by them.

The three methods are: FInalize (), dispose (), close ().

1. Finalize () is the destructor to clear unmanaged resources.

Define the method in the class:

Public classname {

~ Classname ()

{

// Clear unmanaged resources (such as closing file and database connections)

}

}

It features:

1. Operation uncertainty.

It is managed by the garbage collector. This method is called when the garbage collector is working.

2. High performance overhead.

The way the garbage collector works is that if the object executes the finalize () method, the garbage collector puts it in a special queue when it is executed for the first time; this object will be deleted only during the second execution.

3. Definitions and calls cannot be displayed. They are defined as destructor.

Based on the above features, it is best not to execute the finalize () method unless the class does need it or is used together with the other two methods.

II. The dispose () method clears all resources to be cleared, including managed and unmanaged resources.

Definition:

Public void dispose ()

{

// Clear the resources to be cleared (including managed and unmanaged resources)

System. gc. suppressfinalize (this); // This sentence is very important. The reasons are explained below.

}

Its features:

1. Any customer code should call this method to release resources.

2. For the first reason, a backup is generally required, which is generally assumed by the destructor.

3. The class defining this method must inherit the idisposable interface.

4. The syntax keyword using is equivalent to calling dispose (). When using, it calls the dispose () method by default. Therefore, the using class must inherit the idisposable interface.

The dispose () method is flexible and can be released immediately when resources are not needed. It is the final processing of the resource. Calling it means that the object will be deleted.

3. Close () method, which temporarily handles the resource status and may be used later. Generally, it processes unmanaged resources.

Definition:

Public viod close ()

{

// Set the status of unmanaged resources, such as closing the file or database connection

}

Its features:

You can set the status of an unmanaged resource to close the file or database connection.

 

The following is a comprehensive and classic example. The Code demonstrates the functions of each part: (To save trouble, this example is fabricated from the Internet. You only need to explain the problem, what do you mean. I would like to thank the original code creators for writing such a classic and easy-to-understand code. We have benefited a lot !)

Public class resourceholder: System. idisposable

{

Public void dispose ()

{

Dispose (true );

System. gc. suppressfinalize (this );

// The above line of code prevents the garbage collector from calling the destructor in this class

//"~ Resourceholder ()"

// Why do you want to prevent it? Because if you remember to call the dispose () method

// "The Garbage Collector" does not need to "let alone" Release the "unmanaged resources" again.

// If the user does not remember to call it, let the "Garbage Collector" help us to "do more" ^_^

// It doesn't matter if you don't understand what I said above. I have more details here!

}

 

Protected virtual void dispose (bool disposing)

{

If (disposing)

{

// Here is the user code segment for clearing "managed resources.

}

// Here is the user code segment for clearing "unmanaged resources. This is the actual execution code of the destructor. In order to avoid the Customer Code forgetting to display the backup made by calling the dispose () method.

}

 

~ Resourceholder ()

{

Dispose (false); // here is to clear "unmanaged resources"

}

}

 

If you do not understand the above Code, you must read the following explanation carefully. It is classic and you will regret it if you do not read it.

Here, we must be clear,The user must call the method dispose () instead of the method dispose (bool ),However, the actual release method here is not dispose (), but dispose (bool )! Why? Take a closer look at the Code. In dispose (), dispose (true) is called. When the parameter is "true", it is used to clear all managed and unmanaged resources; you must remember that as I said before, "using the Destructor is used to release unmanaged resources", since dispose () can release unmanaged resources, what else do I need to analyze the constructor? In fact, the role of the Destructor is only a "backup "!

Why??

To put it bluntly, any class that executes the interface "idisposable" must call the dispose () method of this class sooner or later as long as the programmer uses the object instance of this class in the code, at the same time, if the class contains the use of unmanaged resources, you must also release the unmanaged resources! Unfortunately, if the code for releasing unmanaged resources is put in the Destructor (The above example corresponds "~ Resourceholder () "), it is impossible for the programmer to call this release code (because the Destructor cannot be called by the user and can only be called by the system, specifically the" Garbage Collector ), therefore, you should know why the "user code segment for clearing unmanaged resources" in the above example is in dispose (bool), rather ~ Resourceholder () in! Unfortunately, not all programmers always remember to call the dispose () method. If the programmer forgets to call this method, it is okay to host resources, in the morning and evening, there will be a "Garbage Collector" to recycle (but it will be postponed for a while). What about unmanaged resources? It is not controlled by CLR! Can the unmanaged resources it occupies never be released? Of course not! We also have the "destructor! If you forget to call dispose (), the "Garbage Collector" will also call the "destructor" to release unmanaged resources! (If the programmer remembers to call dispose (), then the code "system. GC. suppressfinalize (this); "prevents the" Garbage Collector "from calling the destructor, so that you do not have to release" unmanaged resources "one more time) so we are not afraid that programmers will forget to call the dispose () method.

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.