什么是JavaScript垃圾回收?

2020/10/04 22:21 · javascript ·  · 0评论

什么是JavaScript垃圾回收?为了编写更好的代码,对于Web程序员来说,了解JavaScript垃圾回收有什么重要意义?

埃里克·利珀特(Eric Lippert)不久前就此主题撰写了一篇详细的博客文章(另外将其与VBScript进行了比较)。更准确地说,他写了有关JScript的信息,尽管它非常类似于JavaScript,但它是Microsoft自己的ECMAScript实现。我可以想象,您可以假设绝大多数行为对于Internet Explorer的JavaScript引擎都是相同的。当然,不同浏览器的实现方式会有所不同,尽管我怀疑您可以采用一些通用原则并将其应用于其他浏览器。

从该页面引用:

JScript使用了非世代的标记清除垃圾收集器。它是这样的:

  • 每个“范围内”的变量都称为“清除剂”。清道夫可以指数字,对象,字符串等。我们维护一个清道夫列表-变量进入作用域时将移入scav列表,超出范围时将其移出scav列表。

  • 垃圾收集器不时地运行。首先,它在每个对象,变量,字符串等(GC跟踪的所有内存)上都打上“标记”。(JScript在内部使用VARIANT数据结构,并且该结构中有许多额外的未使用位,因此我们只设置其中一个即可。)

  • 其次,它清除了清除剂上的标记以及清除剂引用的可传递性关闭。因此,如果清除剂对象引用了非清除剂对象,则我们清除非清除剂及其所引用的所有内容上的位。(我使用“ closure”一词的含义与我以前的帖子不同。)

  • 至此,我们知道所有仍标记的内存是分配的内存,任何作用域内变量的任何路径都无法访问该内存。指示所有这些对象将其自身拆除,这将破坏任何循环引用。

垃圾收集的主要目的是使程序员不必担心他们创建和使用的对象的内存管理,尽管当然有时并不能避免这种情况-至少对垃圾收集的工作原理有个大概的了解总是有益的。

历史记录:答案的较早版本对delete操作员的引用不正确在JavaScript中delete运算符从对象删除属性,并且与deleteC / C ++完全不同

当涉及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!
    };
}

bigString只要事件处理程序存在,天真的JS实现就无法收集有多种方法可以解决此问题,例如,bigString = null在(的末尾设置init()delete不适用于局部变量和函数参数:delete从对象中删除属性,并且变量对象不可访问-ReferenceError如果您尝试使用严格模式,ES5甚至会抛出a删除局部变量!)。

如果您关注内存消耗,我建议尽可能避免不必要的关闭。

来自博客的好报价

DOM组件是“垃圾收集”的,就像JScript组件一样,这意味着,如果您在任何一个组件中创建一个对象,然后失去对该对象的跟踪,则最终将对其进行清理。

例如:

function makeABigObject() {
var bigArray = new Array(20000);
}

当您调用该函数时,JScript组件将创建一个在函数内可访问的对象(名为bigArray)。但是,一旦函数返回,您就“失去了对bigArray的跟踪”,因为不再有引用它的方法。好的,JScript组件意识到您已经失去了对其的了解,因此清理了bigArray -回收了其内存。DOM组件中也有同样的事情。如果您说document.createElement('div')或类似的内容,那么DOM组件会为您创建一个对象。一旦您以某种方式失去对该对象的跟踪,DOM组件就会清理相关对象。

据我所知,当没有对对象的引用时,会定期对JavaScript对象进行垃圾回收。它是自动发生的,但是如果您想了解更多有关其工作原理的信息,请在C ++级别上查看WebKitV8源代码

通常,您无需考虑它,但是,在较旧的浏览器(例如IE 5.5和IE 6的早期版本,以及当前版本)中,闭包将创建循环引用,如果不对其进行检查,则最终会占用内存。在我所说的关于闭包的特殊情况下,就是在您将JavaScript引用添加到dom对象,将对象添加到DOM对象时又引用了JavaScript对象。基本上,它永远都不会被收集,最终会导致操作系统在循环导致崩溃的测试应用中变得不稳定。实际上,这些泄漏通常很小,但是为了保持代码的清洁,您应该删除对DOM对象的JavaScript引用。

通常,最好使用delete关键字立即取消对已收到回传的JSON数据之类的大对象的引用,并完成对它的任何处理,尤其是在移动Web开发中。这将导致GC的下一次扫描将删除该对象并释放其内存。

垃圾回收(GC)是通过删除不再需要的对象来进行自动内存管理的一种形式。

任何处理内存的过程,请按照下列步骤操作:

1-分配所需的内存空间

2-做一些处理

3-释放此内存空间

有两种主要算法可用来检测不再需要哪些对象。

引用计数垃圾回收:此算法将“不再需要某个对象”的定义简化为“某个对象没有其他引用它的对象”,如果没有引用指向该对象,则将其删除

标记扫描算法:将每个对象连接到根源。任何对象都不会连接到根或其他对象。该对象将被删除。

当前大多数现代浏览器都使用第二种算法。

“在计算机科学中,垃圾回收(GC)是自动内存管理的一种形式。垃圾回收器(或只是垃圾回收器)试图回收垃圾或对象使用的内存,这些对象将不再被应用程序再次访问或更改。”

所有JavaScript引擎都有自己的垃圾收集器,它们可能有所不同。大多数时候,您不必与它们打交道,因为它们只是按照他们的预期去做。

编写更好的代码主要取决于您对编程原理,语言和特定实现的了解程度。

什么是JavaScript垃圾回收?

检查一下

为了编写更好的代码,对于Web程序员来说,了解JavaScript垃圾回收有什么重要意义?

在Javascript中,您无需关心内存分配和释放。整个问题都需要Javascript解释器来解决。在Javascript中仍然可能发生泄漏,但是它们是解释器的错误。如果您对此主题感兴趣,可以在www.memorymanagement.org上阅读更多内容。

在Windows上,您可以使用Drip.exe查找内存泄漏或检查您的免费内存例程是否正常工作。

这非常简单,只需输入网站URL,您就会看到集成IE渲染器的内存消耗。然后单击刷新,如果内存增加,则在网页上的某处发现内存泄漏。但这对于查看IE释放内存的例程是否工作也非常有用。

引用类型不会将对象直接存储到为其分配了变量的变量中,因此本示例中的对象变量实际上并不包含对象实例。相反,它持有指向内存中对象所在位置的指针(或引用)

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

本文地址:http://javascript.askforanswer.com/shenmeshijavascriptlajihuishou.html
文章标签: ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!