我目前正在使用Javascript构建游戏。经过一些测试后,我开始注意到偶然的延迟,这只会是由GC引起的。我决定在它上面运行一个配置文件。结果表明GC实际上是罪魁祸首:
我读到创建新对象会导致很多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并没有太大变化。
您是否还可以提供一些常见的例子,说明可以创建大量垃圾和一些替代品。
谢谢。
答案 0 :(得分:2)
你还可以展示时间轴的记忆吗?如果你有GC问题那些那些应该是明显的,因为你会看到一个锯齿波图。每当图表下降时,GC就会启动,阻止你的线程清空我们的垃圾,这是导致内存相关冻结的主要原因
一般来说,你使用哪个对象实例化并不重要,因为[]
的内存影响很小,你感兴趣的是数组的内容,但要通过你的选择:
选项1:这通常没问题,只考虑一下:闭包。您应该尽可能地避免关闭,因为它们通常是GC的主要原因。
选项2:避免引用范围之外的内容,它对内存没有帮助,并且它会使您的应用程序变慢,因为它必须通过关闭链来查找比赛。这样做没有好处
选项3:永远不会这样做,您总是希望在某处定义x
,否则您会故意泄漏到全局范围内,因此它可能永远不会被GCed < / p>
选项4:这实际上是一个有趣的问题。通常delete x
不执行任何操作,因为delete
仅作用于对象的属性。如果您不知道,delete
实际上返回一个布尔值,表示该对象是否已被删除,因此您可以在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
时,你就是{&1;}。基本上做delete window.b
满足&#34;只删除属性子句&#34;。
不过,不要这样做!
选项5:这个实际上可以节省一点点内存,因为它不需要GC x
,但是它确实需要GC所有内容x
的{{1}}通常比x
本身大得多,因此它不会产生影响
如果您想了解有关内存分析+常见内存性能缺陷的更多信息,这是一篇很棒的文章:http://www.smashingmagazine.com/2012/11/writing-fast-memory-efficient-javascript/