Negative tive C # Principle 16: Garbage Minimization)

Source: Internet
Author: User

Objective C # Principle 16: Minimize garbage
Item 16: Minimize garbage

The garbage collector performs very well in memory management and removes unwanted objects in a very efficient way. However, no matter how you look at it, it takes more time to apply for and release a heap-based memory object than to apply for and release a non-heap-based memory object. You can give some serious performance problems, such as applications.ProgramAllocate excessive referenced objects in a method.

You should not overload the Garbage Collector. For program efficiency, you can use some simple techniques to reduce the work of the garbage collector. All reference types, even local variables, are allocated on the stack. All referenced local variables immediately become spam after the function exits. The most common "spam" approach is to apply for a Windows drawing handle:

Protected override void onpaint (painteventargs E)
{
// Bad. Created the same font every paint event.
Using (font myfont = new font ("Arial", 10.0f ))
{
E. Graphics. drawstring (datetime. Now. tostring (),
Myfont, brushes. Black, new pointf (0, 0 ));
}
Base. onpaint (E );
}

The onpaint () function is called frequently. Every time it is called, another font object is generated, which is actually the same content. The garbage collector needs to clear these objects each time. This will be incredibly inefficient.

Instead, provide the font object from a local variable as an object member and reuse the same object each time a window is drawn:

Private readonly font _ myfont =
New font ("Arial", 10.0f );

Protected override void onpaint (painteventargs E)
{
E. Graphics. drawstring (datetime. Now. tostring (),
_ Myfont, brushes. Black, new pointf (0, 0 ));
Base. onpaint (E );
}

In this way, your program will not produce garbage every time a paint event occurs, and the garbage collector will reduce its work and your program will run a little faster. When you promote a local variable that implements the idisposable interface to a type member, such as a font, your class should also implement the idisposable interface. Principle 18 explains how to complete it correctly.

When a local variable of the reference type (value type does not matter) is frequently used in common function calls, you should promote it as a member of the object. That font is a good example. It is a good candidate object only when common local variables are frequently accessed. You should try to avoid repeatedly creating the same object and use member variables instead of local variables.

The static attribute brushes. Black used in the preceding example demonstrates another technique to avoid repeated creation of similar objects. Use static member variables to create instances of common reference types. Consider the black paint brush used in the previous example. Every time you paint something with a black paint brush, you need to create and release a large number of black paint brushes in the program. The previous solution is to add a member to each class that expects a black brush, but this is not enough. The program may create a large number of windows and controls, which will also create a large number of black paint brushes .. . NET Framework designers are pre-informed of this issue. They create a simple black paint brush for you so that you can reuse it anywhere. The brushes object contains a certain number of static brush objects, each of which has different commonly used colors. Internally, brushes uses inertiaAlgorithmYes, that is, these objects are created only when you use them. A simple implementation method:

Private Static brush _ blackbrush;
Public static brush black
{
Get
{
If (_ blackbrush = NULL)
_ Blackbrush = new solidbrush (color. Black );
Return _ blackbrush;
}
}

When you apply for a black image brush for the first time, the brushes class will create it. However, the brushes class retains a single reference handle of the black brush. When you apply for a new one, it returns the handle directly. The result is that you have created only one black paint brush and are constantly reusing it. In addition, if your application does not need a special resource, a lime green paint brush may never be created. The framework provides a method to restrict objects so that the minimal object set is used when the target is met. Learn to use this technique in your application.

You have learned two techniques to minimize the number of (object) Assignments of an application, just as it undertakes its own tasks. You can promote a frequently used local variable to a class member variable. You can provide a class to store instances of some common given objects in single-piece mode. The last technique also involves creating a constant type of final use value. The system. string class is a constant type. After you create a string, its content cannot be changed. When you writeCodeWhen you modify the content of these strings, you actually create new objects and make the old strings garbage. This seems like an innocent example:

String MSG = "hello ,";
MSG + = thisuser. Name;
MSG + = ". Today is ";
MSG + = system. datetime. Now. tostring ();

This is actually inefficient if you write this statement:

String MSG = "hello ,";
// Not legal, for authentication only:
String tmp1 = new string (MSG + thisuser. Name );
String MSG = tmp1; // "hello" is garbage.
String tmp2 = new string (MSG + ". Today is ");
MSG = tmp2; // "Hello <user>" is garbage.
String tmp3 = new string (MSG + datetime. Now. tostring ());
MSG = tmp3; // "Hello <user>. Today is" is garbage.

The strings tmp1, tmp2, tmp3, and the ("hello") constructed by the original MSG are all junk. + = The method generates a new object in the string class and returns it. It does not modify the results by linking the characters to the original bucket. For the previous example, for a simple construction example, you should use the string. Format () method:

String MSG = string. Format ("Hello, {0}. Today is {1 }",
Thisuser. Name, datetime. Now. tostring ());

For more complex string operations, you should use the stringbuilter class:

Stringbuilder MSG = new stringbuilder ("hello ,");
MSG. append (thisuser. Name );
MSG. append (". Today is ");
MSG. append (datetime. Now. tostring ());
String finalmsg = msg. tostring ();

Stringbuilder is also a variable string class used to generate a constant string object. Before you create a constant string object, it provides an effective method to store variable strings. More importantly, learn such design habits. When your design advocates the use of a constant type (see Principle 7), for some objects that need to be constructed multiple times before they can finally be obtained, you can consider using some object generators to simplify object creation. It provides a way for your users to gradually create (you designed) a constant type and is also used to maintain this type.
Note: Please understand the author's intention. This is only true if you use a constant type. If it is a reference type, you do not have to use the object generator. Pay attention to the characteristics of the constant type, that is, it cannot be changed once it is created, and all modifications will generate new instances. string is a typical example, which is a constant reference type; datetime is also a constant value type .)

The garbage collector is indeed efficient in managing application memory. However, remember that creating and releasing heap objects takes a long time. Avoid creating a large number of objects, and do not create objects that you do not use. Avoid creating referenced objects multiple times in a local function. Instead, provide local variables as type member variables, or create your most common object instance as a static object. Finally, we consider using a mutable object generator to construct a constant object.
======================================

Item 16: Minimize garbage
The garbage collector does an excellent job of managing memory for you, And it removes unused objects in a very efficient manner. but no matter how you look at it, allocating and destroying a heap-based object takes more processor time than not allocating and not destroying a heap-based object. you can introduce serious performance drains on your program by creating an excessive number of reference objects that are local to your methods.

So don't overwork the garbage collector. you can follow some simple techniques to minimize the amount of work that the Garbage Collector needs to do on your program's behalf. all reference types, even local variables, are allocated on the heap. every local variable of a reference type becomes garbage as soon as that function exits. one very common bad practice is to allocate GDI objects in a Windows paint handler:

Protected override void onpaint (painteventargs E)
{
// Bad. Created the same font every paint event.
Using (font myfont = new font ("Arial", 10.0f ))
{
E. Graphics. drawstring (datetime. Now. tostring (),
Myfont, brushes. Black, new pointf (0, 0 ));
}
Base. onpaint (E );
}

 

Onpaint () gets called frequently. every time it gets called, you create another font object that contains the exact same settings. the garbage collector needs to clean those up for you every time. that's incredibly inefficient.

Instead, promote the font object from a local variable to a member variable. Reuse the same font each time you paint the window:

Private readonly font _ myfont =
New font ("Arial", 10.0f );

Protected override void onpaint (painteventargs E)
{
E. Graphics. drawstring (datetime. Now. tostring (),
_ Myfont, brushes. Black, new pointf (0, 0 ));
Base. onpaint (E );
}

 

Your program no longer creates garbage with every paint event. the garbage collector does less work. your program runs just a little faster. when you elevate a local variable, such as a font, that implements idisposable to a member variable, You need to implement idisposable in your class. item 18 explains how to properly do just that.

You shoshould promote local variables to member variables when they are reference types (value types don't matter) and they will be used in routines that are called very frequently. the font in the paint routine makes an excellent example. only local variables in routines that are frequently accessed are good candidates. infrequently called routines are not. you're trying to avoid creating the same objects repeatedly, not turn every local variable into a member variable.

The Static Property brushes. black, used earlier extends strates another technique that you should use to avoid repeatedly allocating similar objects. create static member variables for commonly used instances of the reference types you need. consider the black brush used earlier as an example. every time you need to draw something in your window using the color black, you need a black brush. if you allocate a new one every time you draw anything, you create and destroy a huge number of black brushes during the course of a program. the first approach of creating a black brush as a member of each of your types helps, but it doesn' t go far enough. programs might create dozens of windows and controls, and wocould create dozens of black brushes. the. net Framework designers anticipated this and created a single black brush for you to reuse whenever you need it. the brushes class contains a number of static brush objects, each with a different common color. internally, the brushes class uses a lazy evaluation algorithm to create only those brushes you request. A simplified implementation looks like this:

Private Static brush _ blackbrush;
Public static brush black
{
Get
{
If (_ blackbrush = NULL)
_ Blackbrush = new solidbrush (color. Black );
Return _ blackbrush;
}
}

 

The first time you request a black brush, the brushes class creates it. the brushes class keeps a reference to the single black brush and returns that same handle whenever you request it again. the end result is that you create one black brush and reuse it forevermore. furthermore, if your application does not need a special resourcesay, the lime green brushit never gets created. the framework provides a way to limit the objects created to the minimum set you need to accomplish your goals. copy that technique in your programs ..

You 've learned two techniques to minimize the number of allocations your program performs as it goes about its business. you can promote often-used local variables to member variables. you can provide a class that stores Singleton objects that represent common instances of a given type. the last technique involves building the final value for immutable types. the system. string class is immutable: After you construct a string, the contents of that string cannot be modified. whenever you write code that appears to modify the contents of a string, you are actually creating a new String object and leaving the old string object as garbage. this seemingly innocent practice:

String MSG = "hello ,";
MSG + = thisuser. Name;
MSG + = ". Today is ";
MSG + = system. datetime. Now. tostring ();

 

Is just as inefficient as if you had written this:

String MSG = "hello ,";
// Not legal, for authentication only:
String tmp1 = new string (MSG + thisuser. Name );
String MSG = tmp1; // "hello" is garbage.
String tmp2 = new string (MSG + ". Today is ");
MSG = tmp2; // "Hello <user>" is garbage.
String tmp3 = new string (MSG + datetime. Now. tostring ());
MSG = tmp3; // "Hello <user>. Today is" is garbage.

 

The strings tmp1, tmp2, and tmp3, and the originally constructed MSG ("hello"), are all garbage. the + = method on the string class creates a new String object and returns that string. it does not modify the existing string by concatenating the characters to the original storage. for simple constructs such as the previous one, you should use the string. format () method:

String MSG = string. Format ("Hello, {0}. Today is {1 }",
Thisuser. Name, datetime. Now. tostring ());

 

For more complicated string operations, you can use the stringbuilder class:

Stringbuilder MSG = new stringbuilder ("hello ,");
MSG. append (thisuser. Name );
MSG. append (". Today is ");
MSG. append (datetime. Now. tostring ());
String finalmsg = msg. tostring ();

 

Stringbuilder is the mutable string class used to build an immutable String object. it provides facilities for mutable strings that let you create and modify text data before you construct an immutable String object. use stringbuilder to create the final version of a string object. more important, learn from that design idiom. when your designs call for immutable types (see item 7), consider creating builder objects to facilitate the multiphase construction of the final object. that provides a way for users of your class to construct an object in steps, yet maintain the immutability of your type.

the garbage collector does an efficient job of managing the memory that your application uses. but remember that creating and destroying heap objects still takes time. avoid creating excessive objects; don't create what you don't need. also avoid creating multiple objects of reference types in local functions. instead, consider promoting local variables to member variables, or create static objects of the most common instances of your types. finally, consider creating mutable builder classes for immutable types.

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.