Before writing this article actually, I also thought very long, because of the to this thing on the net already very much, but some are read rise or let a person not easily understand, and the memory management in JS, my feeling resembles one of JS secondary division, we won't take seriously too at ordinary times, but once give an issue very intractable. Can manage a problem through understanding the memory in a few JS more at ordinary times so, a few customs are passed in writing code, avoid the problem that memory reveals.
The memory of the lifecycle JS of content essentials memory reclaims common memory divulges case memory lifecycleWithout giving thought to what program language, memory lifecycle is basic it is consistent:
- The memory that allocates your place need uses the memory that allocates (read, write) when needing, release its / remand
In C language, have special memory management interface, resemble Malloc() and Free() . And in JS, administer port without special memory, all memory management are " automatic " . When JS is founding variable, allocate memory automatically, be in unused moment, release automatically. The memory of automatic " of this kind of " reclaims, caused development of a lot of JS not to care memory to reclaim, actually, this is wrong.
The memory in JS reclaimsCite
Rubbish reclaims algorithm basically relies on quotative concept. In the environment of memory management, if an object has the limits of authority that visits another boy or girl friend (concealed type is explicit perhaps) , be called an object to cite another object. For example: Object of a Javascript has archetypal to it adduction (concealed type cites) with the adduction to its attribute (explicit cite) .
Bring maneuver to count rubbish to collect
This is the simplest rubbish collects algorithm. This is algorithmic " whether does the object need no longer " simplify the definition is " the object has other target to cite it " . If did not cite,point to this object (0 cite) , the object reclaims mechanism be reclaiminged by rubbish. Give typical examples:
Let Arr = [1, 2, 3, 4];arr = Null; // [1, 2, 3, 4] was not cited at this moment, can be reclaimed automatically
Limitation: Cite circularly
In the example below, two objects object is founded and cite each other, caused a loop to cite. Function scope won't leave after they are called, so they had not been used, can be reclaimed. However, bring maneuver to count algorithm to have at least one times each other considering them cite, so they won't be reclaimed.
Function F() {Var O1 = {}; Var O2 = {}; O1.p = O2; // O1 cites O2 O2.p = O1; // O2 cites O1. A loop can be formed to cite here}f();
Concrete example:
Var Div;window.onload = Function(){Div = Document.getElementById("myDivElement"); Div.circularReference = Div; Div.lotsOfData = New Array(10000).join("*");};
In above example, myDivElement the CircularReference attribute in this DOM element cited MyDivElement, caused a loop to cite. IE 6, 7 use bring maneuver to count means to undertake rubbish reclaim to DOM object. The memory when this means often causes an object to be circulated to cite produces leak. Contemporary browser labels through using - cleared memory reclaims algorithmic, will solve this one problem.
Mark - cleared algorithm
This algorithm " whether does the object need no longer " simplify the definition is " whether can be the object obtained " .
The object that this algorithm assumes the setting calls a root Root (in Javascript, the root is global object) . Rubbish reclaims implement will begin from the root, find all targets that begin to cite from the root, seek the target that these objects cite next, begin from the root, rubbish reclaims implement it is all and OK to will be found acquisition target and all targets that cannot achieve.
Since 2012, all and contemporary browser used number - cleared memory reclaims algorithmic. All is opposite JavaScript rubbish reclaims algorithmic improvement is to be based on mark - the improvement of cleared algorithm.
The problem of automatic GC
Although automatic GC is very convenient, but we do not know when GC can undertake. If we used many memory in use process,this is meant, and GC falls without the condition that run, or GC cannot reclaim below the circumstance of these memory, the course is possible play dead, with respect to need we are moved this in the hand in the program do a few operations to spark memory reclaims.
What is memory is divulged?
Tell substantially, memory divulges the memory that is needed no longer namely, as a result of some kind of reason, cannot be released.
Common memory divulges case1.Global variable
Function Foo(arg) {Bar = "some Text";}
The variable that was not stated is handled in JS, when the Bar in afore-mentioned example, meeting Bar, in defining global target, window is in the browser go up. The overall situation in the page is variable, just meet after the page is shut only by destroy by melting or burning. So this kind writes a law to be able to cause memory to divulge, what divulge in this example of course is a simple string only, but in actual code, often the situation will be more bad.
Additionally one kind of accident establishs the condition of global variable.
When Function Foo() {This.var1 = "potential Accidental Global";}// Foo is called, this points to global variable (Window)foo();
Foo is called below this kind of circumstance, this was pointed to global variable Window, founded global variable accidentally.
We spoke of the global variable that a few accident circumstances give a definition, there also are a few overall situation variables that we define clearly in code. If use these global variable to use of short duration to collect much data, after remembering be being used, new to its assignment is Null.
2.Not the timer of destroy by melting or burning and callback function
In a lot of libraries, if was used,watching pattern, can provide callback means, will transfer function of a few callbacks. Should remember reclaiming these callback function. Cite the case of a SetInterval.
Var ServerData = LoadData();setInterval(function() {Var Renderer = Document.getElementById('renderer'); If(renderer) {Renderer.innerHTML = JSON.stringify(serverData); }} , every 5 seconds call 5000); //
If follow-up Renderer element is moved to divide, whole timer does not have any action actually. But if you did not reclaim timer, whole timer still effective, not only timer cannot be reclaimed by memory, the dependence in timer function also cannot reclaim. The ServerData in this case also cannot be reclaimed.
3.Shut a bag
In JS development, we often can be used shut a bag, an in-house function, visit having right includes the variable in his exterior function. This kind of circumstance falls below, shut a bag to also can cause memory to divulge.
The adduction of Var TheThing = Null;var ReplaceThing = Function () {Var OriginalThing = TheThing; Var Unused = Function () {If (originalThing) // to 'originalThing' Console.log("hi"); }; TheThing = {LongStr: New Array(1000000).join('*') , someMethod: Function () {Console.log("message"); } };};setInterval(replaceThing, 1000);
This paragraph of code, when calling ReplaceThing every time, theThing was obtained include a vast array and a boy or girl friend that include SomeMethod to be being shut newly. At the same time Unused is one cited of OriginalThing shut a bag.
The key of this example depends on, shutting share scope between Bao Zhi, although Unused may be not called all the time, but SomeMethod may be called, can bring about memory to cannot undertake reclaiming to its. When this paragraph of code is carried out repeatedly, memory can grow continuously.
The more description of this problem sees this article of Meteor group.
4.DOM cites
A lot of moment, we are right the operation of Dom, can save the adduction of Dom in an array or in Map.
Var Elements = {Image: Document.getElementById('image')};function DoStuff() {Elements.image.src = 'http://example.com/image_name.png';}function RemoveImage() {Document.body.removeChild(document.getElementById('image')); // this moment we still have to cite to #image, image element, still cannot be reclaimed by memory. }
In afore-mentioned case, although we undertook moving dividing to Image element, but the adduction that still has pair of Image elements, still cannot undertake to its memory reclaims.
Need an attention additionally one is nodded is, to the adduction of the leaf node that a Dom cultivates. Cite a case: If we cited the Td element in a form, once whole form was deleted in Dom, we feel memory reclaims intuitionisticly should reclaim the other element besides the Td that is cited. But in fact, this Td element is the one stature element of whole form, withhold the adduction to its father element. This can be brought about to whole form, cannot undertake memory reclaims. So we want the tread lightly adduction to Dom element.
Brief summaryWhen we are writing code at ordinary times, the likelihood operates the business of memory management field rarely, but the meaning that we want to have memory management side, especially above a few kinds of causes memory leak possibly conditions that I offer, discretion wants when writing code.