[Reading Notes] C # advanced programming Chapter 1 memory management and pointer,

Source: Internet
Author: User

[Reading Notes] C # advanced programming Chapter 1 memory management and pointer,

(1) Background Memory Management

1. Value Data Type

Windows uses a virtual addressing system that maps available memory addresses of programs to actual addresses in Hardware Memory, this task is managed by Windows in the background (32-bit each process can use 4 GB virtual memory, 64-bit more, this memory includes executable code and loaded DLL, and the variable content used when the program is running ).

In the virtual memory of the processor, there is a region called Stack. Stack storage is not the value data type of the object member.

When variables are released, they are always in the opposite order of memory allocation. This is how the stack works.

When the program runs for the first time, the stack pointer points to the end of the memory block reserved for the stack. Stack is actually downward filled, that is, from the high memory address to the low memory address. When data is imported into the stack, the stack pointer is adjusted accordingly to always point to the next idle unit.

 

2. Reference Data Type

The managed heap uses a method (new operator) to allocate memory. After exiting the method, the data stored in the heap remains available for a long time. Unlike the stack, the memory on the stack is allocated upwards.

The process of setting up referenced variables is more complex than that of setting up value types, which cannot avoid system overhead of performance. When a referenced variable is out of scope, it will be deleted from the stack, but the referenced data will remain in the heap until the program ends and the garbage collector will delete it, the modified data is deleted only when it is no longer referenced by any variable.

 

3. Garbage Collector

When the Garbage Collector releases all objects that can be released, it moves other objects back to the end of the heap and forms a continuous block again.

The first part of the heap is called The 0th generation. The newly created object will be moved to this part. The objects retained after each running of the garbage collector are compressed and moved to the next-generation storage part.

In. NET, a large object has its own heap, which is called an elephant heap. When you use objects larger than 85000 bytes, they are placed on this special stack.

The second generation and the elephant Stack are now recycled in the background thread.

The GCSettings. LatencyMode attribute controls how the Garbage Collector recycles garbage.

 

(2) Release unmanaged Resources

The garbage collector does not know how to release unmanaged resources (file handles, network connections, and database connections). It needs to develop special rules to ensure that the unmanaged resources are released when an instance of the recycle class is released.

  • Declare An destructor (or Terminator) as a member of the class.
  • Implement the IDisposable Interface

 

1. destructor

The Destructor syntax has no return type, no parameters, no access modifier, and a waveform (~) prior to the same name as the class (~).

Class MyClass {~ MyClass () {// destructor }}

C # The Destructor cannot determine when to execute. C # The implementation of destructor will delay the time when the object is finally deleted from the memory.

 

2. IDisposable Interface

In C #, The System. IDisposable interface is recommended to replace the destructor. The IDisposable interface declares a Disposable () method, which returns void without parameters.

Class MyClass: IDisposable {public void Dispose () {// release }}

Call the Dispose () method:

MyClass my = new MyClass (); // code my. Dispose ();

In this release method, if an exception is thrown in the Process Code, the Dispose () method is not called, resulting in the memory being not released.

MyClass my = new MyClass (); try {// code} finally {my. Dispose ();}

With the preceding call method, you can avoid the Process Code throw an exception and the memory is not released. You can also use the using keyword to simplify the call. The effect is the same as above.

Using (MyClass my = new MyClass () {// code}

 

 

(3) Insecure code

1. Direct Access to memory using pointers

The pointer is only a variable that stores the address in the same way as the reference.

 

(1) Use the unsafe keyword to write Insecure code

The keyword used for Insecure code is unsafe.

Unsafe class MyClass // insecure class {unsafe public string Name {get; set;} // insecure attribute unsafe void SayHi () // Insecure Method {Console. writeLine ("Hi! "+ Name);} void SayBay () {unsafe int * pAge; // insecure local variables must be in unsafe methods. The Console. WriteLine (" Bye! "+ PAge );}}

 

(2) pointer syntax

When the code block is marked as unsafe, the pointer is declared using the following syntax:

int* age;

After declaring pointer-type variables, you can use them in the same way as normal variables, but you must first learn the other two operators ", * Indicates "Get address content ".

int x = 10;int* pX = &x;int y = *pX;

The pointer can be declared as any value type.

 

(3) Forcibly convert the pointer to the integer type

Since pointers actually store an integer that represents an address, the addresses in any pointer can be converted to any integer type.

int x = 100;ulong* pY = (ulong*)x;

Note that, in a 32-bit system, an address occupies 4 bytes and converting the pointer to a non-uint, long, or ulong may cause overflow errors, A 64-bit system occupies 8 bytes of an address. If you convert the pointer to a non-ulong value, an overflow error occurs. Note that pointer overflow cannot be checked by the checked keyword. Because the. NET Runtime Library assumes that if you use pointers, you will know what you are doing, so you don't have to worry about overflow.

 

(4) forced conversion between pointer types

byte b = 10;byte* pB = &b;double* pD = (double*)pB;

 

(5) void pointer

byte b = 10;byte* pB = &b;void* pV = (void*)pB;

The void pointer is mainly used to call the API functions that require the void * parameter.

 

(6) pointer arithmetic operations

You can add or subtract integers from the pointer. Add the value X to the pointer of the T type. If the value of the pointer is P, P + X * (sizeof (T) is obtained )).

byte b = 10;byte* pB = &b;pB--;

If the two pointer types are the same, one pointer can be subtracted from the other. In the result, the value of one long type is the result of division of the number of bytes occupied by the two difference types.

byte b1 = 10;byte* pB1 = &b1;byte b2= 11;byte* pB2 = &b2;long l = pB1 - pB2;

 

(7) sizeof Operator

The sizeof operator is used. Its parameter is the name of the data type, and the number of characters of this type is returned.

int x = sizeof(int);//4

 

(8) structure pointer: access operator for pointer members

The structure pointer works in the same way as the predefined Value Type pointer. However, there is a condition that the structure cannot contain any reference type, because the pointer cannot point to any reference type.

MyStruct * pStruct; MyStruct myStruct = new MyStruct (); pStruct = & myStruct; // access the structure member value (* pStruct) through a pointer ). X = 4; // another syntax * pStruct-> X = 4;

 

(9) class member pointer

You cannot create a pointer to the class because the garbage collection period does not maintain any information about the pointer. It only maintains reference information, and the heap will be moved during the garbage collection process, this will cause pointer pointing errors. To solve this problem, you need to use the fixed keyword to tell the Garbage Collector not to move these objects.

MyClass myClass = new MyClass (); fixed (double * pX = & (myClass. x) // multiple such pointers can be placed before the code block Multiple fixed (long * pX = & (myClass. y), pZ = & (myClass. z) // you can declare {fixed (long * pW & (myClass. w) // nested declaration {}}

 

2. Use pointers to optimize performance

1. Create a stack-based array

A major application area of pointers: Creating arrays with high performance and low system overhead in the stack. To create a high-performance array, another Keyword: stackalloc is required. The stackalloc command prompts that the. NET Runtime Library allocates a certain amount of memory on the stack (the number of bytes occupied by the Data Type multiplied by the number of items ). When calling the stackalloc command, you must provide the data type to be stored (which must be a value type) and the number of data items to be stored.

decimal* pDecimal = stackalloc decimal[10];

The number of items can also be a variable:

int size = 5;decimal* pDecimal = stackalloc decimal[size];

Stackalloc always returns a pointer to the allocated data type, pointing to the top of the newly allocated memory block.

You can use the pointer algorithm to access the next element of the array. Use the expression * (pDecimal + X) to access the Elements marked as X in the array.

* PDecimal = 1; // array 1st items * (pDecimal + 1) = 2; // array 2nd items C # Another method is defined to access the array, the method is the same as the normal array access method. PDecimal [0] = 1; // equivalent to * pDecimal = 1; pDecimal [1] = 2; // equivalent to * (pDecimal + 1) = 2;

Note that the compiler cannot check the variables when using pointers. When the number of accessed items exceeds the number of allocated items, an exception is thrown at runtime.

pDecimal[20] = 21;

When using pointers to achieve high performance, you also have to pay some price: You need to make sure you know what you are doing, otherwise it will throw a very strange running error.

 

 

 

Related Article

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.