JavaScript garbage collection and memory management

Source: Internet
Author: User

JavaScript has an automatic garbage collection mechanism (Gc:garbage collecation), which means that the execution environment is responsible for managing the memory used during code execution. In languages such as C and C + +, a basic task for developers is to manually track memory usage, which is a source of many problems.

When writing JavaScript programs, developers no longer care about memory usage issues, the allocation of required memory, and the recycling of useless memory are fully automated management. The rationale for this garbage collection mechanism is simple: identify variables that are no longer in use, and then release the memory they occupy. to do this, the garbage collector periodically performs this operation at a fixed time interval (or a predetermined collection time in code execution).

Due to the existence of the garbage collector, many people think that JavaScript is not too concerned about memory management, but if you do not understand the memory management mechanism of JavaScript, we are also very vulnerable to memory leaks (memory cannot be recycled).

// 1. Objects New  new45
 new 1 2 3 4 
// 3. Strings, JavaScript strings and. NET, use resource pools and copy on write to manage strings.  New String ("Hello hyddd""<p> " " </p> "
// 4. Functions var x =new Function (code)
function outer (name) {     var x = name;         return function inner () {         return"" + name;      }  }
The life cycle of memory

Let's examine the normal life cycle of local variables in the function.

    • Memory allocation: Local variables exist only in the process of function execution. In this process, the local variables are allocated the appropriate space on the stack (or heap) memory to store their values.
    • Memory usage: Then use these variables in the function until the function execution is finished.
    • Memory Reclamation: There is no need for local variables to exist at this time, so they can be freed up for future use.

It is often easy to tell if a variable is still necessary, but it is not always easy to reach a conclusion in all cases (e.g. when using closures). The garbage collector must keep track of which variables are useful and which ones are useless, marking variables that are no longer useful for future recall of their occupied memory. The policy used to identify the useless variable may vary by implementation, but there are typically two policies: Mark purge and reference count , depending on the implementation in the browser.

Mark Clear

The most common method of garbage collection in JavaScript is tag cleanup (mark-and-sweep). When a variable enters the environment (for example, when declaring a variable in a function), the variable is marked as "entering the environment." Logically, it is never possible to release the memory used by variables entering the environment, because they may be consumed as long as the execution flow enters the appropriate environment. When the variable leaves the environment, it is marked as "out of the environment."

function Test () {     var//    var/ after execution, A and B are marked out of the environment and recycled. 

The garbage collector will tag all variables stored in memory at run time (of course, you can use any markup method). It then strips out variables in the environment and tags of variables referenced by variables in the environment (for example, closures). Variables that are tagged later will be considered as variables to be deleted because variables in the environment are inaccessible to those variables. Finally, the garbage collector completes the memory cleanup work, destroys those tagged values, and reclaims the memory space that they occupy.

The main disadvantage of this approach is that if some objects are cleaned up, the memory is not contiguous, even if the memory consumption is not high, for example, only 50%, but because of too much memory space, later large objects can not even be stored in memory. The general processing method is in the garbage collection after the finishing operation, this method is also called labeling , the process of sorting is to copy the discontinuous memory to one end, so that the discontinuous memory up.

Currently, JavaScript implementations of ie9+, Firefox, Opera, Chrome, and Safari all use a tag-clear garbage collection strategy (or similar strategy), except that the time interval for garbage collection is different.

Reference count

Another less common garbage collection strategy is called Reference counting (reference counting). The meaning of the reference count is the number of times each value is referenced by the tracking record. When a variable is declared and a reference type value is assigned to the variable, the number of references to that value is 1. If the same value is assigned to another variable, the number of references to that value is added by 1. Conversely, if a variable that contains a reference to this value has another value, the number of references to the value is reduced by 1. When the number of references to this value becomes 0 o'clock, it means that there is no way to access the value again, so that it can reclaim the memory space it occupies. In this way, the next time the garbage collector runs, it frees the memory used by those values with zero reference count

function Test () {     var//    var//      var//    var//}

Many browsers used the reference counting strategy early on, but soon it ran into a serious problem: circular referencing . A circular reference refers to a pointer to object B that is contained in object A, and object B contains a reference to object A. Take a look at the following example:

function problem () {    varnew  Object ();     var New Object ();     = OBJECTB;     = objecta;}

In this example, Objecta and OBJECTB are referred to each other by their respective properties, that is, both objects have a reference count of 2. In implementations that take a markup cleanup policy, these two objects leave the scope after the function executes, so this mutual reference is not an issue. However, in implementations with reference counting policies, objecta and OBJECTB will continue to exist when the functions have been executed, because their references will never be 0. If this function is repeated multiple calls, it will result in a large amount of memory not being recycled. For this reason, a new generation of browsers abandons the reference count and instead uses tag cleanup to implement its garbage collection mechanism. However, the trouble with reference counting does not end there.

We know that some of the objects in IE are not native JavaScript objects. For example, the objects in their BOM and DOM are implemented using C + + as COM (Component object model, Component object models) objects, and the garbage collection mechanism of COM objects is a reference counting strategy. Therefore, even though the JavaScript engine of IE is implemented using the tag purge policy, the COM objects that JavaScript accesses are still based on the reference counting policy. In other words, whenever a COM object is involved in IE, there is a circular reference problem. The following simple example shows a circular reference problem that is caused by using a COM object:

var element = document.getElementById ("some_element"); var New  == myObject;

This example creates a circular reference between a DOM element and a native JavaScript object (myObject). Where the variable MyObject has a property named element pointing to the element object, and the variable element has a property called the Someobject callback MyObject. Since this circular reference exists, even if the DOM in the example is removed from the page, it will never be recycled.

To avoid circular reference problems like these, it is best to manually disconnect the native JavaScript object from the DOM element when you do not use them. For example, you can use the following code to eliminate the circular reference created by the previous example:

Nullnull;

Set the variable to null mean that the connection between the variable and its previously referenced value is cut off. The next time the garbage collector runs, the values are removed and the memory they occupy is reclaimed.

To solve these problems, IE9 has converted both BOM and DOM objects into real JavaScript objects. This avoids the problems caused by the coexistence of two garbage collection algorithms, and eliminates the common memory leaks.

Performance issues with IE6

IE6 garbage collection is run according to memory allocation, when there are 256 variables in the environment, 4,096 objects, 64k strings in any case, it will trigger the garbage collector to work, looks very scientific, do not have to call once a period of time, sometimes it is not necessary, so on-demand call is not very good? But if there are so many variables in the environment, and now the script is so complex, the garbage collector will work all the time, so the browser won't play.

Microsoft has made the adjustment in the IE7, the trigger condition is no longer fixed, but the dynamic modification, the initial value and IE6 the same, if the garbage collector's memory allocation is less than 15% of the memory allocated by the program, the majority of memory can not be recycled, the garbage collection trigger condition is too sensitive, when the critical conditions doubled, If the amount of memory reclaimed is higher than 85%, it means that most of the memory is already cleaned up, and the various thresholds are reset back to the default values. This seemingly simple adjustment greatly improves the performance of IE7 when running pages that contain a lot of JavaScript.

Coding Note-Dereference

By using a language that has a garbage collection mechanism, developers generally do not have to worry about memory management issues. However, the problems that JavaScript faces in memory management and garbage collection are a bit different. One of the main problems is that the amount of available memory allocated to a Web browser is typically less than that allocated to a desktop application. This is done primarily for security reasons, in order to prevent the Web page running JavaScript from exhausting all system memory and causing the system to crash. Memory throttling issues not only affect allocating memory to variables, but also affect the call stack and the number of statements that can be executed concurrently in one thread.

Therefore, make sure that you use the least amount of memory for better performance on your page. The best way to optimize memory consumption is to save only the necessary data for the code in execution. Once the data is no longer useful, it is best to null release its reference by setting its value to -this is called dereferencing (dereferencing). This practice applies to most global variables and properties of global objects. Local variables are automatically dereferenced when they leave the execution environment, as shown in the following example:

function Createperson (name) {    varnew  Object ();     = name;     return Localperson;} var globalperson = Createperson ("Nicholas"); // manually de-Globalperson references null;

Since a local localPerson variable createPerson() leaves its execution environment after the function has been executed, it is not necessary for us to explicitly dereference it. But for a global variable globalPerson , we need to manually dereference it when we're not using it, which is the last line of code in the example above.

However, releasing a reference to a value does not mean that the memory consumed by the value is automatically reclaimed. The real effect of dereferencing is to leave the value out of the execution environment so that it can be reclaimed the next time the garbage collector runs.

Optimization strategy of garbage collection

Like other languages, JavaScript's garbage collection policy does not prevent one problem: when garbage collection stops responding to other actions, it is for security reasons. While JavaScript garbage collection at 100ms or more, the general application is OK, but for JavaScript games and animation, this is more consistent requirements for the application, it is troublesome. This is the point at which the new engine needs to be optimized: avoid long-time stop responses caused by garbage collection.

Uncle David mainly introduced 2 optimization schemes, and this is the main 2 optimization solutions:

Generational recycling (Generation GC)

This is consistent with the idea of a Java recycling strategy. The goal is to reduce the time spent per GC by distinguishing between "temporary" and "persistent" objects, and by reclaiming the "temporary object area" (young Generation), and by less reclaiming the "persistent object area" (tenured generation), reducing the number of objects that need to be traversed each time. The V8 engine used by Chrome is the generational recycling strategy

JavaScript garbage collection and memory management

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.