[Turn] js garbage collection mechanism

JavaScript has an automatic garbage collection mechanism, and the execution environment is responsible for managing the memory used during code execution. When writing javascript programs, developers no longer need to care about memory usage, and the allocation of required memory and the recycling of useless memory are fully automated. The following will introduce the garbage collection mechanism of javascript in detail

 

principle

  The principle of the garbage collection mechanism is very simple: find out those variables that are no longer in use, and then release the memory occupied by them. operate

  Local variables only exist during the execution of the function. During this process, corresponding space is allocated on the stack (or heap) memory for local variables in order to store their values. These variables are then used in the function until the end of the function execution. At this point, there is no need for local variables to exist. So their memory can be freed for future use. In this case, it is easy to judge whether the variable is still necessary; but it is not so easy to draw conclusions in all cases

  The garbage collector has to keep track of which variables are useful and which are not, marking variables that are no longer useful so that the memory they occupy can be reclaimed in the future. Strategies for identifying useless variables usually include mark-sweeping and reference counting

 

mark clear

  The most common method of garbage collection in javascript is mark-and-sweep . When a variable enters the environment (eg, a variable is declared in a function), the variable is marked as ' entering the environment '. Logically, the memory occupied by variables entering an environment can never be freed, because they may be used as soon as execution flow enters the corresponding environment. And when the variable leaves the environment , it is marked as ' leaving the environment '

  Variables can be marked in any way. For example, you can record when a variable enters the environment by flipping a special bit, or use a list of variables 'into the environment' and a list of variables 'out of the environment' to keep track of which variable has changed. At the end of the day, it doesn't really matter how you label the variables, it's the strategy that matters

  When the garbage collector runs, it marks all variables stored in memory . Then, it unmarks variables in the environment and variables referenced by variables in the environment. Variables marked after this will be treated as variables ready for deletion, because variables in the environment are no longer accessible. Finally, the garbage collector completes the memory cleanup, destroying those marked values ​​and reclaiming the memory space they occupied

  Most browser implementations use a mark-and-sweep garbage collection strategy, although the timing of garbage collection varies.

 

reference counting

  Another less common garbage collection strategy is called reference counting

  The meaning of reference counting is to keep track of the number of times each value is referenced . When a variable is declared and a reference type value is assigned to the variable, the number of references to this value is 1, and if the same value is assigned to another variable, the number of references to this value is incremented by 1. On the contrary, if the variable containing the reference to this value has obtained another value, the number of references to this value is reduced by 1. When the number of references to this value is 0, it means that there is no way to access this value anymore, so you can Reclaim the memory space it occupies. In this way, when the garbage collector runs next time, it will free the memory occupied by those values ​​whose reference count is 0

  Netscape Navigator 3.0 was the first browser to use the reference counting strategy, but soon it encountered a serious problem - circular reference: object A contains a pointer to object B, and object B also contains a pointer to object A pointer

copy code
function problem(){
    var objectA = new Object();
    var objectB = new Object();

    objectA.someOtherObject = objectB;
    objectB.anotherObject = objectA;
}
copy code

  In this example, objectA and objectB refer to each other through their respective properties, and both objects have a reference count of 2. In an implementation with a mark-sweep strategy, since both objects go out of scope after the function executes, this mutual reference is not a problem. But in the implementation using the reference counting strategy, after the function is executed, objectA and objectB will continue to exist, because their reference count will never be 0. If this function is called multiple times, a large amount of memory will not be recovered.

  Some objects in IE are not native JavaScript objects. For example, the objects in its BOM and DOM are implemented in the form of COM (component Object Model) objects using C++, and the garbage collection mechanism of COM objects uses reference counting Strategy. Therefore, even though IE's javascript engine is implemented using a mark-sweep strategy, the COM objects accessed by javascript are still based on a reference counting strategy. In other words, as long as COM objects are involved in IE, there is a problem with circular references

var element = document.getElementById('some_element');
var myObject = new Object();
myObject.element = element;
element.someObject = myObject;

  This example creates a circular reference between a DOM element ( element ) and a native javascript object ( myObject ). Among them, the variable myObject has an attribute named element that points to the element object, and the variable element also has an attribute named someObject that points to myObject. Because of this circular reference, even if the DOM in the example is removed from the page, it will never be recycled

  为了避免类似这样的循环引用,最好是在不使用它们的时候手工断开原生javascript和DOM元素之间的连接

myObject.element = null;
element.someObject = null; 

  将变量设置为null意味着切断变量与它此前引用的值之间的连接。当垃圾收集器下次运行时,就会删除这些值并回收它们占用的内存

  为了解决此问题,IE9把BOM和DOM对象都转换成了真正的javascript对象

 

性能问题

  垃圾收集器是周期性运行的,而且如果为变量分配的内存数量很可观,那么回收工作量也是相当大的。在这种情况下,确定垃圾收集时间间隔是一个非常重要的问题

  IE的垃圾收集器是根据内存分配量运行的。具体一点说,就是256个变量,4096个对象(或数组)字面量和数组元素(slot)或者64kb的字符串。达到上述任何一个临界值,垃圾收集器就会运行

  这种实现方式的问题在于,如果一个脚本中包含那么多变量,那么该脚本很可能会在其生命周期中一直保有那么多的变量。而这样一来,垃圾收集器就不得不频繁地运行。结果,由此引发的严重性能问题促使IE7重写了其垃圾收集例程

  IE7的javascript引擎的垃圾收集例程改变了工作方式:触发垃圾收集的变量分配、字面量和数组元素的临界值被调整为动态修正。IE7中的各项临界值在初始时与IE6相等。如果垃圾收集例程回收的内存分配量低于15%,则变量、字面量和数组元素的临界值就会加倍。如果例程回收了85%的内存分配量,则将各种临界值重置回默认值。这样,极大地提升了IE在运行包含大量javascript的页面时的性能

  事实上,在有的浏览器中可以触发垃圾收集过程。在IE中,调用window.CollectGarbage()方法会立即执行垃圾收集

 

内存管理

  The main problem with using javascript with garbage collection is that the amount of available memory allocated to a web browser is usually less than that allocated to a desktop application, in order to prevent the webpage running javascript from exhausting all system memory and causing the system to crash. Memory limit issues affect not only memory allocated to variables, but also the call stack and the number of statements that can be executed concurrently in a thread

  Therefore, ensuring the least amount of memory is used for better performance of the page. And the best way to optimize memory footprint is to save only necessary data for the executing code . Once the data is no longer useful, it is best to release its reference by setting its value to null, a practice called dereferencing. This applies to most global variables and properties of global objects, local variables are automatically dereferenced when they leave the execution context

copy code
function createPerson(name){
    var localPerson = new Object();
    localPerson.name = name;
    return localPerson;
}

var globalPerson = createPerson('test');
globalPerson = null;
copy code

  Note, however, that dereferencing a value does not automatically reclaim the memory occupied by the value. The real effect of dereferencing is to get the value out of the execution context so that it can be collected by the garbage collector the next time it runs

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324395372&siteId=291194637