JS Promotion--discussion on front-end memory leak

Source: Internet
Author: User

1.IE7/8 a DOM object or ActiveX object Circular Reference causes a memory leak

Circular references are divided into two types:

First: multiple objects circular references

var a=new  Object; var b=New  OBJECT;A.R=b;b.r=a;

  The second type: circular referencing yourself

var a=New  OBJECT;A.R=a;

for ECMAScript objects, as long as there are no other objects referencing objects A, B, which means they are only references to each other, are still recognized and processed by the garbage collection system.

However, in IE7, IE8 , if any object in a circular reference is a DOM node or an ActiveX object, such as var a = document.getElementById ("#a"), the garbage collection system will not find a circular relationship between them. Because the DOM recovery mechanism of IE and JS recovery mechanism is not the same. There are two kinds of JS recycle mechanism: Mark clear and reference count , reference count has a memory leak for garbage collection of circular reference , and the DOM recycle mechanism of IE uses reference count. ie9+ There is no circular reference causing a DOM memory leak, either by Microsoft or by the way the DOM is recycled.

I picked up the apple from the bottom. Learn about JavaScript garbage collection mechanism and memory management

 Second, the mark to clear JS the most commonly used garbage collection method is marked 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 ." functionTest () {varA = 10;//be marked, into the environment varb = 20;//be marked, into the environment}test (); //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 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.
The reference count reference count means that the number of times each value is referenced is tracked. 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. functionTest () {varA = {};//A has a reference count of 0 varb = A;//a quoted number plus 1, which is 1 varc =a;//a quoted number plus 1 for 2 varb ={};//a quoted number minus 1, to 1Netscape Navigator3 is the first browser to use a reference counting policy, 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. functionfn () {varA = {}; varb ={}; 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 in the DOM and the objects in the BOM are using C++implemented in the form of COM objects, and the garbage collection mechanism of COM objects is a reference counting strategy. 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. varelement = document.getElementById ("Some_element");varMyObject =NewObject (); MYOBJECT.E=ELEMENT;ELEMENT.O=MyObject; 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 doingwindow.onload=functionouterfunction () {varobj = document.getElementById ("element")); Obj.onclick=functioninnerfunction () {};}; This code looks fine, but obj references document.getElementById ("element"), while document.getElementById ("element")  The OnClick method will refer to variables in the external environment, and naturally also includes obj, is not very covert ah. The simplest way to do this is to manually remove the circular reference, such as the function you justmyobject.element=NULL; ELEMENT.O=NULL;window.onload=functionouterfunction () {varobj = document.getElementById ("element")); Obj.onclick=functioninnerfunction () {}; 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 the IE9+ There is no circular reference causing a DOM memory leak, either Microsoft has optimized it, or the DOM recycling has changed

Examples of circular references described above

window.onload=function  outerfunction () {var obj = document.getElementById ("element") ;  Obj.onclick=function  innerfunction () {};};

It is also possible to understand a memory leak caused by a closed-loop reference . How do you understand that?

first , obj is an external object, and the function defined by Obj.onclick implicitly calls the object obj (this is the object obj in the Obj.onclick function). Then we need to know Obj.onclick is actually a outerfunction external function, why? DOM Listener events cannot be local scopes, they are global scopes, you see. So DOM triggering this event is equivalent to calling Obj.click () outside the function outerfunction, and the event internally uses the outerfunction variable, obj, which forms a closure. The reference count of the IE7/IE8 Dom can never reclaim this Dom object. In any case, this is a memory leak caused by a DOM circular reference, and a normal closure does not cause a memory leak.

Change to the following structure

window.onload=function  outerfunction () {  var obj = document.getElementById ("element") );  $ (obj). Click (function  innerfunction () {});};

jquery binding events are not bound directly to the DOM object, but are bound using the jquery cache. See jquery Event Architecture

  Even if a closure is still created at this point, and it will cause the same loop as before, the code here does not cause a memory leak in IE. Because jquery takes into account the potential hazards of a memory leak, it manually frees all of the event handlers that it has specified (jquery source code $.fn.remove the processing of the cache release of the node in the function ). As long as you stick to the event binding method of jquery, you don't have to worry about a memory leak caused by this particular common cause.

But that does not mean that we are completely out of the woods. When you do other things with DOM elements, keep an eye out for them. Whenever you assign a JavaScript object to a DOM element, you may cause a memory leak in the old version of IE. jquery only helps to reduce the likelihood of this happening.

With this in mind, jquery provides us with another tool to avoid such leaks. Attaches the information to the DOM element using the. Data () method. Since the data here is not stored directly in the extended attribute (jquery uses an internal object and the ID that it creates to hold the data here), it never constitutes a reference loop, thus effectively avoiding the memory leak problem. This is how the jquery event bindings are used.

  

2. Underlying DOM leaks

When the original DOM is removed, the child node references are not removed and cannot be reclaimed .

var select = document.queryselector; var treeref = Select (' #tree '); var leafref = Select (' #leaf ');   // Leafref is a sub-node of treefre in the COM tree Select (' body '). RemoveChild (TREEREF); // #tree不能被回收入, because Treeref is still here.

Workaround:

NULL ; // The tree cannot be recycled, because the leaf results leafref still NULL ; // now #tree can be released.

DOM Insertion Order causes memory leaks

When a dynamically created 2 different range of DOM objects are attached together, a temporary object is created. When this DOM object changes scope to document, that temporary object is useless, and the temporary object is not recycled and will cause a memory leak. If we add each of these two DOM to the original DOM object in our province, there will be no intermediate temporary objects. See understanding and resolving IE memory leaks page cross-leaked cross-page Leaks.

3.Timer Timer leak

var val = 0; for (var i = 0; i < 90000; i++) { var buggyobject = { function() { varthis; = SetTimeout (function() { ref.callagain (); 90000);} } Buggyobject.callagain ();

You can't recycle buggyobject at this time.

// Although you want to recycle, but the timer's still there. null;

Workaround, Stop the timer first and then recycle

// workaround, Stop the timer first  null;

Recommended memory leaks article:

Understanding and resolving IE memory leaks (Chinese translation): Http://www.tuicool.com/articles/2AZ3y2

Understanding and resolving IE memory leaks (English version): https://msdn.microsoft.com/en-us/library/bb250448.aspx

JS memory leaks In several situations: http://blog.csdn.net/li2274221/article/details/25217297

  If you feel this article is good, please click on the bottom right "recommended"!

JS Promotion--discussion on front-end memory leak

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.