160930. JavaScript garbage collection mechanism and memory management

Source: Internet
Author: User

First, garbage collection mechanism-GC

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.

Principle: The garbage collector periodically (periodically) finds variables that are not in use and releases its memory.

The mechanism of JavaScript garbage collection is simple: Identify variables that are no longer in use, and then release the memory they occupy, but the process is not real-time, because the overhead is large, so the garbage collector executes periodically at fixed intervals.

The variables that are no longer used are the end-of-life variables, and of course only local variables, the life cycle of the global variables, until the browser unload page ends. Local variables exist only during the execution of a function, and in this process the local variables are allocated space on the stack or heap to store their values, and then use these variables in the function until the function ends, and the outer function is not considered an end because of the intrinsic function in the closure.

or the code description:

function fn1 () {var obj = {name: ' Hanzichi ', age:10};} function fn2 () {var obj = {name: ' Hanzichi ', age:10}; return obj;} var a = fn1 (); var B = fn2 ();

Let's see how the code executes. First defined two function, respectively called FN1 and fn2, when FN1 is called, into the FN1 environment, will open up a memory storage object {name: ' Hanzichi ', age:10}, and when the call is over, out of the FN1 environment, The block memory is automatically freed by the garbage collector in the JS engine, and the returned object is pointed to by the global variable B during FN2 's call, so the block memory is not freed.

Here's the question: Which variable is useless? So the garbage collector has to keep track of which variables are useless, mark the variables that are no longer useful, and get their memory back in the future. Policies that are used to mark useless variables may differ by implementation, typically in two ways: Mark Purge and reference count. Reference counts are less common, and tag cleanup is more commonly used.

Second, Mark Clear

The most common way of garbage collection in JS is to mark clear. When a variable enters the environment, for example, when a variable is declared in a function, the variable is marked as "going into 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 a = 10;//is marked, enters environment  var b = 20;//is marked, enters environment}test ();//After execution, a and B are marked out of the environment and are recycled.

The garbage collector will tag all variables stored in memory at run time (of course, you can use any markup method). It then removes variables from the environment and tags (closures) of variables referenced by variables in the environment. 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.

So far, the JS implementations of IE, Firefox, Opera, Chrome, and Safari are all using a garbage collection strategy or similar strategy for tag cleanup, except that the time interval for garbage collection is different.

Iii. 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 that is used by those values that have a reference count of 0.

function test () {var a = {};//a has a reference count of 0  var b = A;//a with a reference count of 1, 1  var c =a;//a's reference count is 1, 2 var b ={}, and the number of references in//a minus 1. is 1}

Netscape Navigator3 is the first browser to use a reference counting strategy, but soon it encounters 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.

function fn () {var a = {}; var b = {}; a.pro = b; b.pro = A;} FN ();

The above codes A and B are all 2,FN () after execution, two objects have left the environment, there is no problem in the markup cleanup mode, but under the reference counting policy, because the number of references A and B is not 0, the garbage collector does not reclaim the memory, if the FN function is called heavily, Will cause a memory leak. On IE7 and IE8, the memory line goes up.

We know that some of the objects in IE are not native JS objects. For example, its memory leaks objects in the DOM and BOM are implemented in the form of COM objects using C + +, and the garbage collection mechanism of COM objects is a reference counting policy. Therefore, even if the JS engine of IE is implemented with the tag purge policy, the COM object that JS accesses is still based on the reference counting policy. In other words, whenever a COM object is involved in IE, there is a circular reference problem.

var element = document.getElementById ("Some_element"), var myObject = new Object (), myobject.e = ELEMENT;ELEMENT.O = Myobje Ct

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

Look at the above example, there are classmates back to feel too weak, who would do such a boring thing, in fact, we are not doing

Window.onload=function outerfunction () {var obj = document.getElementById ("element"); obj.onclick=function Innerfunction () {};};

This code looks fine, but obj references document.getElementById ("element"), while document.getElementById ("element") The OnClick method will refer to the external environment of the German variable, naturally also include obj, is not very covert ah.

Solutions

The simplest way is to manually remove the circular reference, such as the function just now can

myobject.element = NULL;ELEMENT.O = null;

Window.onload=function outerfunction () {var obj = document.getElementById ("element"); obj.onclick=function Innerfunction () {}; Obj=null;};

Setting a variable to null means that the connection between the variable and the value it previously referred to is cut off. The next time the garbage collector runs, the values are removed and the memory they occupy is reclaimed.

It is important to note that ie9+ does not have a circular reference causing a DOM memory leak, either Microsoft has optimized it, or the DOM's recycling has changed

Iv. Memory Management

1. When will the garbage collection be triggered?

The garbage collector runs periodically, and if you allocate a lot of memory, the recycling process can be daunting, and determining the garbage collection interval becomes a problem worth thinking about. 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 and normal, the result is that the garbage collector has been working, so the browser is not going to play.

Microsoft IE7 in the adjustment, the trigger condition is no longer fixed, but dynamic modification, the initial value and IE6 the same, if the garbage collector to reclaim memory allocation is less than 15% of the memory of the program, the majority of memory can not be recycled, set garbage collection trigger conditions are too sensitive, when the street conditions doubled, If the recovered memory is higher than 85%, it means that most of the memory should be cleaned up, and then the trigger condition is set back. This makes the garbage collection job a lot more functional.

2. Reasonable GC Scheme

1), JavaScript engine basic GC scheme is (simple GC): Mark and Sweep (Mark Clear), i.e.:

    • (1) Traverse all accessible objects.

    • (2) Reclaim objects that are inaccessible.

2), GC defects

Like other languages, the GC policy of JavaScript does not prevent one problem: When GC stops responding to other operations, this is for security reasons. While the JavaScript GC in 100ms or more, the general application is OK, but for the JS game, animation for the consistency of the application of high requirements, it is troublesome. This is the point at which the new engine needs to be optimized: avoid a long-time stop response by GC.

3), GC optimization strategy

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

(1) 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 recycling the "temporary objects" area (young Generation), and by less reclaiming the "persistent object" area (tenured generation), reducing the number of objects that need to traverse each time.

What you need to add here is that there is extra overhead for tenured generation objects: migrating it from young generation to tenured generation, and, if referenced, the point of reference that needs to be modified.

(2) Incremental GC
The idea of this scheme is simple: "deal with a little bit at a time, next time, and so on."

This scheme, although short-time, but more interruptions, brings the problem of frequent context switching.

Because each scenario has its own scenario and disadvantage, the actual application will be based on the actual situation of the selection scheme.

For example: Low (object/s) ratio, interrupt the frequency of GC execution, simple GC is lower, if a large number of objects are long-term "survival", then the advantages of generational processing is not much.

160930. JavaScript garbage collection mechanism 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.