ArticleDirectory
- When Will stringbuilder be used?
- Capacity of stringbuilder
This article discusses the following:
- There are two main types of memory-consuming objects in the Website: managed resources and unmanaged resources.
- The lifecycle of the managed resource.
- Reduce the memory usage of hosted and unmanaged resources.
- Reduce the memory used by the session. If improperly used, the session will occupy a lot of memory.
Managed resources
Managed resources are stored inCodeObject created on the stack using the new keyword.
Lifecycle
When you call New to create an object, the memory is allocated on the managed stack. This will only be sent at the end of the allocated area, which will be very efficient.
When CLR allocates memory for an object at the end of the allocation area, spam starts if there is not enough space. This removes all objects that are not referenced and compresses the surviving objects. This will generate continuous space at the end of the allocated area.
When all references of an object leave their scope or they are set to null, this object can be garbage collected. However, it will be physically deleted only during the next garbage collection, which may not happen immediately. This means that an object will continue to use the memory for a period of time after it is no longer used. Interestingly, the longer an object is used, the more likely it will remain in the memory after all references are lost, depending on its generation.
Generation
When the Garbage Collector collects garbage, it accesses a large number of objects and checks whether they can be collected. This operation is very expensive. To reduce costs, CLR assumes the fact that objects with longer time are less likely to lose their references than recently created objects. This means that it makes sense to prioritize the inspection of objects passing through the year.
ThisAlgorithmBy dividing all objects into three generations: 0, 1, and 2. Each object starts from generation 0. If it survive a garbage collection, it is upgraded to generation 1. If the first generation object survive the next garbage collection, it will be upgraded to the second generation. The second-generation object survived the next garbage collection, or the second-generation object.
Objects of generation 0 are frequently collected, followed by generation 1 and generation 2. Therefore, the longer an object will survive, the longer it takes to remove all its references.
When the first generation object is collected, the zero generation object is also collected. When two generations of objects are collected, One and zero generations are collected. Therefore, higher object collection costs are higher.
Large Object heap
In addition to the heap mentioned below, a large object heap is also used for pushing more than 85kb objects. If the large object heap or the second generation object does not have enough space, the large object heap collection and the second generation object collection will be triggered. Because the collection of the second generation object will collect all the objects of the second generation, this operation is costly.
Objects on the large object Stack are not compressed during collection. Therefore, if a large object of different sizes is assigned to the large object stack, a lot of unreallocated space will be left between objects.
Counter
Use the following counters in the. net clr memory classification in perfmon:
- Percent Time in GC: percentage of time consumed on GC after the last collection.
- Gen 0 heap size: Maximum number of bytes that can be allocated to the 0-generation object before the next 0-generation garbage collection. This is not the current number of bytes allocated to the 0-generation object.
- Gen 1 heap size: the number of bytes occupied by generation 1 objects. This is not the maximum number of words that a generation object may use.
- Gen 2 heap size: the number of bytes occupied by generation 2 objects. This is not the maximum number of words that a two-generation object may use.
- Large Object heap size: size of the large object heap.
- # Bytes in all heaps: Sum of Gen 0 heap size, Gen 1 heap size, Gen 2 heap size, and large object heap size. It indicates the memory occupied by all managed objects.
- # Gen 0 collections: SinceProgramNumber of times a zero-generation object is collected after startup.
- # Gen 1 collections: the number of times a generation 1 object has been collected since the program was started.
- # Gen 2 collections: the number of times a 2-generation object has been collected since the program was started.
CLR profiler
CLR profiler is a free tool for Microsoft to display program memory usage. Download CLR profiler from the following address:
For how to use CLR profiler, refer to its instructions.
Garbage Collector
The following methods can be used to optimize the performance of the garbage collector:
- Late Retrieval
- Early release
- Use stringbuilder to connect strings
- Use compare for case-insensitive comparison
- Use response. Write Buffer
- Pooled objects larger than 85kb
Late Retrieval
Create an object as soon as possible. This saves memory and reduces their lifetime so that they are less likely to be upgraded to higher-generation objects. Specifically:
-
- Do not create objects before long operations.
NoLargeobject = new largeobject (); // long running database call... largeobject. mymethod ();
Instead
// Long running database call... largeobject = new largeobject (); largeobject. mymethod ();
Do not pre-allocate memory except for objects larger than 85kb. Pre-allocated systems with no garbage collection Based on. NET, such as real-time systems, may be very effective. However, in. net, this does not have any advantages.
-
If you use. Net 4, consider lazy <t>.
Lazy <expensiveobject> expensiveobject = new lazy <expensiveobject> ();
Unlike normal class instantiation, this does not create an object. This object will only be created when it is referenced for the first time.
Early release
If you only need to use an object for a short time, make sure it does not have a long reference. Otherwise, the garbage collector will not know that it can be collected, or even upgrade it to a high-generation object.
If you need to reference a short-term object in a long-term object, set its reference to null when you no longer need this short-term object:
Largeobject = new largeobject (); // create referece from long lived object to new large objectlonglivedobject. largeobject = largeobject; // reference no longer neededlonglivedobject. largeobject = NULL;
In a class, if an attribute references a short-term object and before performing a long operation, if you no longer need this short-term object, set the reference to null.
Private largeobject {Get; set;} public void mymethod () {largeobject = new largeobject (); // some processing... largeobject = NULL; // more lengthy processing ...}
This is not necessary for local variables (variables defined in the method), because the compiler can determine when the variables will not be used.
When to use stringbuilder to connect strings without using stringbuilder
- When the number of string connections is less than 7.
- When a string is connected in a statement, only one final string is generated.
S = S1 + S2 + S3 + S4;
Capacity of stringbuilder
The stringbuilder can accept a capacity parameter. The default value is 16. Each time the stringbuilder exceeds the capacity, it will allocate a buffer with the original capacity double, copy the content in the old buffer to the new buffer, and leave the old buffer to the garbage collector.
Therefore, if you know the size of the result string, setting the capacity parameter in the stringbuilder will improve the performance.
Use compare for case-insensitive comparison
Not used:
// Tolower allocates two new stringsif (S. tolower () = s2.tolower ()){}
Usage:
If (string. Compare (S1, S2, true) = 0 ){}
The above Code uses current culture. Byte comparison is faster:
If (string. Compare (S1, S2, stringcomparison. ordinalignorcase) = 0 ){}
Use response. Write Buffer
Not used:
// Concatenation creates intermediate stringresponse. Write (S1 + S2 );
Use
Response. Write (S1); response. Write (S2 );
Use the same technology for htmltextwrite objects when using custom controls.
Pooled objects larger than 85kb
Frequent allocation and collection of objects larger than 85kb are expensive operations, which also results in memory fragmentation.
If the website needs to instantiate a class larger than 85kb, consider creating a pool for these objects when the program starts, instead of creating each time.
When determining whether an object exceeds 85kb, determine whether it occupies the space itself or only references the object that occupies so much space. For example, a byte array with 85*1024 = 87040 elements occupies 85kb:
Byte [] takes85kb = new byte [87040]; // 85*1024 = 87040
However, an array that References 85 objects and occupies 1024 bytes of each object does not occupy that much space, because this array only includes Object references.
Unmanaged Resources
Some frequently used objects are based on unmanaged resources, such as file handles and database connections. These resources are scarce resources. The garbage collector also removes all references from these objects and releases the scarce resources they use. But it is best to release them immediately after they are not used for other threads.
Idisposable
The object implementing idisposable provides the dispose () method, which releases the object. They often implement the same close () method as the dispose method, although the close () method is not a member of the idisposable.
If an object implements the idisposable interface, call the dispose () method as soon as possible, instead of caching these objects.
To ensure that unmanaged resources can be released as soon as possible even if an exception is thrown, dispose () is generally called in the final code block ():
Sqlconnection connection = new sqlconnection (connectionstring); try {// use connection...} finally {connection. Dispose ();}
You can use the using statement in C:
Using (sqlconnection connection = new sqlconnection (connectionstring) {// use connection...} // connection. Dispose called implicitly
There is no need to wait until the using statement Automatically releases the connection. If you call dispose () for released objects, no error is generated.
Using (sqlconnection connection = new sqlconnection (connectionstring) {// use connection... connection. dispose (); // long running code that doesn't use the connection ...} // connection. dispose is called Again implicitly
If you create a class that contains objects that implement idisposable, inherit from a class that implements idisposable, or include unmanaged objects provided by the operating system, you need to implement idisposable. For more information, see:
- Idisposable interface: http://msdn.microsoft.com/en-us/library/system.idisposable.aspx? Ppud = 4
- Implement idisposable interface: http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx? Ppud = 4
Counter
Category:. Net CLR memory
# Of pinned objects: The pinned object encountered in the last garbage collection. Unmanaged code uses pinned objects. The garbage collector cannot move a pinned object. All objects may cause heap fragments.
Category:. Net CLR locksandthread
# Of Current Logical threads: Number of. Net thread objects used in applications. If this number continues to rise, it is constantly creating new threads without removing old threads and their stacks.
Category: Process
Private Bytes: The size of memory allocated by the current process that cannot be shared with other processes. The memory allocated by the unmanaged object is equivalent to private bytes-# bytes in all heaps (. net clr memory classification ).
Sessions
Session state allows users to store information among multiple requests. In the default inproc mode, the information is stored in the memory. This method is the fastest, but it does not work if there are multiple servers, because the next request from the same visitor may be processed by another server. The StateServer and SQL Server modes meet the needs of multiple servers. They store information on the central server or database.
ASP. NET stores session IDs in browser cookies to differentiate sessions of different users. Another method is to store the URL.
ASP. NET does not have a way to determine whether the visitor no longer uses the program, so that the session state can be deleted. To solve this problem, ASP. NET assumes that if a visitor's request is not received in 20 minutes, the session state of the visitor can be deleted. This value is configurable in 20 minutes. This means that the session state occupies at least 20 minutes of memory.
Counter
Category: ASP. NET Applications
Sessions active: Number of active sessions.
If you confirm that the session state occupies too many resources, there are some solutions:
- Reduces the session State survival time.
- Reduce the space occupied by the session state.
- Use another session mode.
- Do not use session state.
If sessions expires soon, it will consume less memory:
-
- Configure the sessionstate element in Web. config:
<Configuration> <system. Web> <sessionstate mode = "inproc" timeout = "20"/> </system. Web> </configuration>
You can also use the code Configuration:
Session. Timeout = 20;
When a visitor logs out, the session can be explicitly removed:
Session. Abandon ();
Reduce the space occupied by session state
- Do not store objects with additional overhead. For example, do not store user interface elements or data tables. Only store the required data.
- Store session-independent data in the cache so that all users can share the data. For example, do not store country lists in sessions.
- Do not store data from databases. In this way, the database load will be increased in exchange for a reduction in memory usage. This method is feasible when the data retrieval speed is fast and is not frequent, and the data itself occupies a lot of memory.
Use other session Modes
If the memory is insufficient, you can use sqlserver mode. One benefit of this method is that when the web server or application pool is restarted, the session will not be lost. However, this will increase the load on the database. This mode is used to specify the read-only mode on the page without updating the session state:
<% @ Page enablesessionstate = "readonly" %>
Do not use session state
In many cases, session state is not required at all. There are some alternatives:
- Use ajax to reduce page refreshes. This allows you to save session data on the page.
- Save the session state in viewstate. This can be done when the session state is not very large and is related to pages. However, this will occupy the bandwidth and cause security problems.
The reason for not using the session is that the session ID is stored in the cookie or URL, which damages the cache function.