JavaScript 垃圾收集。创建对象和变量?

标签 javascript garbage-collection

我目前正在使用 Javascript 构建游戏。经过一些测试后,我开始注意到偶尔的延迟,这只能由 GC 启动引起。我决定对其运行一个配置文件。结果表明GC实际上是罪魁祸首:

GC Profile

我读到创建新对象会导致大量 GC。我想知道是否有这样的事情:

var x = [];

也创建任何垃圾,因为 Java 中的原始类型不这样做。由于 Javascript 中没有真正的类型,我不确定。此外,以下哪项最适合产生最少的垃圾:

选项 1:

function do() {
    var x = [];
    ...
}

选项 2:

var x = [];
function do() {
    x = [];
    ...
}

选项 3:

function do() {
    x = [];
    ...
}

或选项 4:

function do() {
    var x = [];
    ...
    delete x;
}

选项 5:

var x = [];
function do() {
    x.length = 0;
    ...
}

在我的例子中,do 函数每秒调用 30 次。它在数组上运行多个操作。

我想知道这一点,因为我只是将所有变量设为全局变量以试图防止它们被 GC 收集,但 GC 并没有太大变化。

您能否也提供一些产生大量垃圾的常见示例和一些替代方案。

谢谢。

最佳答案

能不能把timeline的内存也显示出来?如果您有 GC 问题,那么这些问题应该很明显,因为您会看到锯齿波图。每当图形下降时,就是 GC 启动,阻止您的线程清空我们的垃圾,这是内存相关卡住的主要原因

锯齿波图示例(蓝色图为内存):enter image description here

一般来说,您使用哪个对象实例并不重要,因为 [] 对内存的影响很小,您感兴趣的是数组的内容,但是通过你的选择:

选项 1:这通常没问题,但需要考虑一个因素:闭包。您应该尽量避免关闭,因为它们通常是 GC 的主要原因。

选项 2: 避免引用范围之外的内容,这对内存没有帮助,而且会使您的应用变慢一些,因为它必须向上移动闭包链才能找到匹配项.这样做没有任何好处

选项 3:永远不要这样做,你总是想在某个地方定义 x 否则你会故意泄漏到全局范围内,因此它可能永远不会被 GC

选项 4: 这实际上是一个有趣的选项。通常 delete x 不会执行任何操作,因为 delete 仅作用于对象的属性。如果您不知道,delete 实际上会返回一个 bool 值,表示该对象是否已被删除,因此您可以在 chrome 控制台中运行此示例:

function tmp () {
    var a = 1;
    delete a; // false
    console.log('a=', a) // 1

    b = 2;
    delete b; // true !!!
    console.log('b=', b) // Exception
}
tmp();

什么?!好吧,当你说 b = 2(没有 var)时,它和写 window.b = 2 是一样的,所以当你 delete b,您基本上是在执行 delete window.b,它满足“仅删除属性子句”。 不过,不要这样做!

选项 5:这个选项实际上为您节省了一点点内存,因为它不需要 GC x,但是:它确实必须 GC 所有x 的内容通常比 x 本身大得多,因此不会有什么不同

如果您想了解有关内存分析和常见内存性能陷阱的更多信息,这是一篇很棒的文章:http://www.smashingmagazine.com/2012/11/writing-fast-memory-efficient-javascript/

关于JavaScript 垃圾收集。创建对象和变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33317506/

相关文章:

java - -Xms : Initial heap size or minimum heap size?

javascript - tableDnD - 只为 <tr> 中的一个 <td> 启用拖放

python - 完成后我应该删除大对象以在 python 中使用它们吗?

javascript - 如何使用javascript将json数据导出到excel文件?

javascript - Math.random 不断返回相同的答案

java - Android JNI native 代码中的 C++ 对象是否调用垃圾回收?

java - 垃圾收集和回调

java - Full GC 频繁发生

javascript - 带有固定顶部菜单的翻转菜单

javascript - 使用 Javascript 将文本和变量写入 HTML