The js memory management content has been relatively scattered before contact, recently in this piece to do some systematic learning. Some summaries of the learning process are shared with you here. Welcome criticism and correction, learn together and make progress together.
Some languages provide memory management interfaces, such as MALloc () and free() in C. In JavaScript, memory is allocated and reclaimed automatically, and the word “automatic” has led many developers to believe that we don’t need to worry about memory, which is a mistake. Memory management to avoid memory leakage is also an important part of performance optimization.
The life cycle of a variable
Javascript variables have a separate life cycle, and for global variables, their life cycle lasts until the page closes (which involves one way of leaking memory summarized below). For local variables, after the execution of the function’s code, the life cycle of the local variable ends, and the memory it occupies is released through the garbage collection mechanism (garbage collection).
Garbage collection mechanism
Garbage collection is usually done in two ways:
Reference counting
This algorithm is described in the MDN documentation as the most “naive” garbage collection algorithm; The core principle is this: To determine whether an object should be recycled, you need to see if there are any references to it, and if there are “zero references “, then recycle. This algorithm is naive because it has a more serious flaw — circular reference:
function f(){ var o = {}; var o2 = {}; o.a = o2; // o reference o2 o2. A = o; // o2 references oreturn "azerty";
}
f();
Copy the code
The first thing to note is that we are talking about this in the functional scope, not the global environment. Older versions of IE used this strategy for non-javascript native objects such as DOM and BOM objects. Memory leaks occur when:
var el =document.getElementById("some_element");
var Obj =new Object();
myObj.el = el;
el.someObject = Obj;
Copy the code
Of course we can release it manually when not in use:
myObj.el = null;
el.someObject = null;
Copy the code
Mark clear
This algorithm simplifies the definition of “whether an object is no longer needed” to “whether an object is available”.
This algorithm assumes an object with a root; In Javascript, the root is the global object, corresponding to the browser’s window and node’s global. The garbage collector will periodically start at the root, find all the objects referenced from the root, and then find the objects referenced by those objects… Starting at the root, the garbage collector finds all reachable objects and collects all unreachable objects.
The advantage of this algorithm over reference counting is that “objects with zero references” are always unavailable, but the opposite is not necessarily so, see “circular references”.
Since 2012, all modern browsers have used the mark-sweep garbage collection algorithm, which is optimized on this basis. All of the improvements to JavaScript garbage collection algorithms are based on improvements to the mark-sweep algorithm, not on improvements to the mark-sweep algorithm itself and its simplified definition of whether an object is no longer needed.
Limitations: Objects that cannot be queried from the root object will be purged. Of course, this is rarely the case in our development practice, which is one of the reasons we ignore memory management.
Common examples of memory leaks
1. Forget to declare local variables
function a(){
b=2
console.log('B is not declared! ')}Copy the code
B is not declared and will become a global variable and will not be released until the page closes. Using strict mode can be avoided.
2. Memory leaks from closures
var leaks = (function(){
var leak = 'xxxxxx'; // a reference in a closure is not recycledreturn function(){
console.log(leak);
}
})()
Copy the code
Of course, sometimes we keep this variable in memory on purpose, but we want to avoid inadvertent memory leaks.
3. RemoveDOM
Node forgets to remove a temporary value
Sometimes, for performance purposes, a variable is used to hold a node temporarily so that it is not retrieved from the DOM for later use. However, when removing the DOM node, forgetting to remove the reference to the DOM node from the temporary variable can also cause memory leaks
var element = {
image: document.getElementById('image'),
button: document.getElementById('button')}; document.body.removeChild(document.getElementById('image')); // If element is not reclaimed, it is useless to remove the image node. The image node is still in memory.Copy the code
Similarly, if the DOM node is bound to an event, but the event is not unbound at the time of removal, it is useless to simply remove the DOM node
4. The memory of the timer leaks
var someResource = getData();
setInterval(function() {
var node = document.getElementById('Node');
if(node) { node.innerHTML = JSON.stringify(someResource)); }}, 1000);Copy the code
If there is no clear timer, the someResource will not be released, and if it happens to take up a lot of memory, it can cause performance problems. Also mention setTimeout, which can reclaim the memory of the object referenced in its callback after it finishes timing. Of course, some scenarios may have very long setTimeout timings, which should also be taken into account.
Chrome view
You can view the original version in Timeline and the new version in Performance:
Steps:
- Open developer tools
Performance
- Check the
Screenshots
和memory
- Top left dot starts record
- To stop recording
The part of the Heap corresponding to the figure shows that there is a periodic fall in the memory and also the cycle of garbage collection. If the minimum value (called min) after garbage collection keeps increasing, then there must be a serious memory leak problem.
On the use of tools here for the time being tasted, and then in-depth study of all aspects of the use of developer tools to share with you.
Reference Documents:
- MDN document
- I recommend a PPT to you
Spread the word
This article is published in Front of Mint Weekly. Welcome to Watch & Star.