什么是JavaScript垃圾收集?为了编写更好的代码,web程序员了解JavaScript垃圾收集的重要方面是什么?
当前回答
垃圾收集(GC)是通过删除不再需要的对象来自动进行内存管理的一种形式。
任何处理内存的进程都遵循以下步骤:
1 -分配你需要的内存空间
2 -做一些处理
3 -释放这个内存空间
有两种主要的算法用于检测哪些对象不再需要。
引用计数垃圾收集:该算法将“一个对象不再需要”的定义简化为“一个对象没有其他对象引用它”,如果没有引用点,该对象将被删除
标记扫描算法:将每个对象连接到根源。任何对象都不连接根或其他对象。该对象将被移除。
目前大多数现代浏览器使用第二种算法。
其他回答
什么是JavaScript垃圾收集?
检查这个
对于web程序员来说,了解JavaScript垃圾收集的重要一点是, 为了写出更好的代码?
在Javascript中,你不关心内存分配和释放。整个问题都需要Javascript解释器来解决。在Javascript中泄漏仍然是可能的,但它们是解释器的错误。如果你对这个话题感兴趣,你可以阅读更多 www.memorymanagement.org
当涉及到DOM对象时,要注意循环引用:
JavaScript中的内存泄漏模式
请记住,只有在没有对对象的活动引用时才能回收内存。这是闭包和事件处理程序的一个常见陷阱,因为一些JS引擎不会检查内部函数中实际引用了哪些变量,而只是保留封闭函数的所有局部变量。
这里有一个简单的例子:
function init() {
var bigString = new Array(1000).join('xxx');
var foo = document.getElementById('foo');
foo.onclick = function() {
// this might create a closure over `bigString`,
// even if `bigString` isn't referenced anywhere!
};
}
只要事件处理程序存在,简单的JS实现就不能收集bigString。有几种方法可以解决这个问题,例如在init()末尾设置bigString = null (delete对局部变量和函数参数不起作用:delete将从对象中删除属性,并且变量对象不可访问-如果您试图删除局部变量,ES5在严格模式下甚至会抛出ReferenceError !)
如果您关心内存消耗,我建议尽可能避免不必要的闭包。
据我所知,JavaScript的对象在没有对对象的引用时周期性地进行垃圾收集。这是自动发生的事情,但如果你想了解更多关于它是如何工作的,在c++级别,看一看WebKit或V8源代码是有意义的
Typically you don't need to think about it, however, in older browsers, like IE 5.5 and early versions of IE 6, and perhaps current versions, closures would create circular references that when unchecked would end up eating up memory. In the particular case that I mean about closures, it was when you added a JavaScript reference to a dom object, and an object to a DOM object that referred back to the JavaScript object. Basically it could never be collected, and would eventually cause the OS to become unstable in test apps that looped to create crashes. In practice these leaks are usually small, but to keep your code clean you should delete the JavaScript reference to the DOM object.
通常,使用delete关键字立即取消对JSON数据等大对象的引用是一个好主意,特别是在移动web开发中。这将导致GC的下一次扫描删除该对象并释放其内存。
在javascript中,垃圾收集是不确定的,对象何时会被清除,或者是否会被清除。这适用于强引用的对象。强引用对象不受垃圾回收的影响。
在ES12之后,可以执行以下实现来检查对象何时被垃圾收集。
要了解更多关于javascript垃圾收集的知识,你可以使用ES12之后可用的终结器。
let a = new Array(200).fill(true);
构造定稿器
const cleanup = new FinalizationRegistry(key => {
// your code here
});
cleanup.register(a, 'wewew');
对象'a'现在不可达,终结器回调将在垃圾收集后发生
引用类型不将对象直接存储到变量中 它被赋值了,下面例子中的对象变量,实际上没有 包含对象实例。相反,它持有指向的指针(或引用) 内存中对象存在的位置。
var object = new Object();
如果将一个引用类型变量赋值给另一个引用类型变量,则每个变量 获取指针的副本,两者仍然引用中相同的对象 内存。
var object1 = new Object();
var object2 = object1;
JavaScript是一种垃圾收集语言,所以实际上不需要这样做 使用引用类型时,要考虑内存分配问题。然而, 最好取消对不再需要的对象的引用,以便垃圾 收集器可以释放该内存。最好的方法是设置 对象变量为null。
var object1 = new Object();
// do something
object1 = null; // dereference
在使用数百万个对象的大型应用程序中,取消引用对象尤其重要。
摘自《面向对象的JavaScript原则》——NICHOLAS C. ZAKAS