当前位置: 首页 > 面试题库 >

JavaScript中的垃圾回收如何工作?

孟智志
2023-03-14
问题内容

JavaScript中的垃圾回收如何工作?它类似于.NET垃圾回收吗?难道是因为人们在VBScript中实现垃圾回收很不好,所以人们避免了垃圾回收并建立了对JavaScript作为其标准客户端语言的偏好?


问题答案:

垃圾收集如何工作?

简短的答案是:当某个内存块(例如某个对象)不再可访问时,有资格回收它。何时,如何回收或是否回收它完全取决于实现,并且不同的实现方式也不同。但是在语言级别,它是自动的。

例如:

function foo() {
    var bar;

    bar = new ReallyMassiveObject();
    bar.someCall();
}

foo返回时,目标bar指向是自动进行垃圾回收,因为没有什么留给有对它的引用。

与:

function foo() {
    var bar;

    bar = new ReallyMassiveObject();
    bar.someCall();
    return bar;
}
// elsewhere
var b = foo();

…现在,对该对象的引用在调用后仍然存在,并且一直持续到/除非调用者将其他内容分配给范围bb超出范围。

还要对比:

function foo() {
    var bar;

    bar = new ReallyMassiveObject();
    bar.someCall();
    setTimeout(function() {
        alert("Three seconds have passed");
    }, 3000);
}

在这里,即使在foo返回之后,计时器机制也会引用计时器回调,而计时器回调(_闭包)_也会引用创建它的上下文,该上下文又包含bar变量。结果,从理论上讲,bar所指的内容在foo返回时不能立即用于垃圾收集。取而代之的是,它一直保持到定时器触发并释放其对回调的引用,从而使回调及其所引用的上下文符合GC的条件。(实际上,现代JavaScript引擎可以并且可以在可能的地方优化闭包。例如,在上文中,静态分析显示回调未引用bar,并且不包含任何evalnewFunction可能在运行时动态引用它的代码,因此JavaScript引擎可以安全地将bar函数所引用的上下文排除在外,从而使它所引用的内容符合GC的要求,而现代人则可以。

JavaScript在清理循环引用btw方面没有问题,例如:

function foo() {
    var a, b;

    a = {};
    b = {};
    b.refa = a;
    a.refb = b;
}

foo返回时,这一事实a被提及b,反之亦然是没有问题的。由于没有其他任何内容涉及它们中的任何一个,因此它们都可以清除。在IE上,如果其中一个对象是主机提供的对象(例如DOM元素或通过创建的对象)而不是JavaScript对象,则情况
并非 如此new ActiveXObject。(因此,例如,如果将JavaScript对象引用放在DOM元素上,并且JavaScript对象又引用了DOM元素,即使没有人引用它们,它们也会彼此保留在内存中。)但这是IE
错误的 问题 ,而不是JavaScript。

回覆:

是因为vbscript GC不好,所以人们将javascript用作他们的标准客户端api吗?

JavaScript是 原始的
客户端Web脚本语言。VBScript只是在Microsoft推出浏览器之后才出现,并且仅在Microsoft浏览器中受支持。如果您想使用最广泛的浏览器,JavaScript曾经是并且是唯一的客户端脚本编写游戏。
< subjective>它也是经典VBScript的八倍。;-)



 类似资料:
  • 垃圾回收 我们对生产中花了很多时间来调整垃圾回收。垃圾回收的关注点与Java大致相似,尽管一些惯用的Scala代码比起惯用的Java代码会容易产生更多(短暂的)垃圾——函数式风格的副产品。Hotspot的分代垃圾收集通常使这不成问题,因为短暂的(short-lived)垃圾在大多情形下会被有效的释放掉。 在谈GC调优话题前,先看看这个Attila的报告,它阐述了我们在GC方面的一些经验。 Scal

  • 对于开发者来说,JavaScript 的内存管理是自动的、无形的。我们创建的原始值、对象、函数……这一切都会占用内存。 当我们不再需要某个东西时会发生什么?JavaScript 引擎如何发现它并清理它? 可达性(Reachability) JavaScript 中主要的内存管理概念是 可达性。 简而言之,“可达”值是那些以某种方式可访问或可用的值。它们一定是存储在内存中的。 这里列出固有的可达值的

  • 垃圾收集,引用计数,显式分配 和所有的现代语言一样,OCaml提供垃圾收集器,所以你不用像C/C++一样显式地分配和释放内存。 JWZ在他的文章 "Java sucks" rant(Java蛋疼(怒)!): 第一个好家伙是Java没有 free()。其他的都没有所谓了。这几乎掩盖了所有的缺点,不管有多糟糕, 这个有点让后续文档基本都没有意义了,但是...(译注:但是啥大家自己看吧) OCaml的垃

  • 问题内容: 有人可以解释一下G1垃圾收集器的工作原理吗?我还无法在任何地方找到任何全面,易于理解的描述。 谢谢 问题答案: 收集器将堆分成固定大小的区域,并跟踪这些区域中的实时数据。它将一组指针(“记住的集”)保留在区域内和区域外。当认为有必要使用GC时,它将首先收集实时数据较少的区域(因此,“垃圾优先”)。通常,这意味着一步就可以收集整个区域:如果进入一个区域的指针数量为零,则无需对该区域进行标

  • 问题内容: 什么是JavaScript垃圾回收?为了编写更好的代码,对于Web程序员来说,了解JavaScript垃圾回收有什么重要意义? 问题答案: 从该页面引用: JScript使用了非世代的标记清除垃圾收集器。它是这样的: 每个“范围内”的变量都称为“清除剂”。清道夫可以指数字,对象,字符串等。我们维护一个清道夫列表- 变量进入作用域时将移入scav列表,超出范围时将其移出scav列表。 垃

  • 主要内容:垃圾回收器函数,实例Lua 采用了自动内存管理。 这意味着你不用操心新创建的对象需要的内存如何分配出来, 也不用考虑在对象不再被使用后怎样释放它们所占用的内存。 Lua 运行了一个垃圾收集器来收集所有死对象 (即在 Lua 中不可能再访问到的对象)来完成自动内存管理的工作。 Lua 中所有用到的内存,如:字符串、表、用户数据、函数、线程、 内部结构等,都服从自动管理。 Lua 实现了一个增量标记-扫描收集器。 它使用