JavaScript垃圾收集。创建对象和变量? [英] Javascript Garbage Collection. Creating Objects and Vars?

查看:95
本文介绍了JavaScript垃圾收集。创建对象和变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在用Javascript构建一个游戏。经过一些测试后,我开始注意到偶尔会出现滞后,这只能由GC踢进来。II决定在其上运行一个配置文件。结果显示GC实际上是罪魁祸首:



<我读过创建新对象会导致很多GC。我想知道是否是这样的:

  var x = []; 

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

选项1:

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

选项2:

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

选项3:

 函数do(){
x = [];
...
}

或者选项4:

 函数do(){
var x = [];
...
删除x;
}

选项5:

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

do函数被称为30次秒在我的情况。它在阵列上运行几个操作。

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

您还可以提供一些常见的创建大量垃圾和替代方法的示例。



谢谢。

解决方案

您还可以显示时间线?如果您有GC问题,那么您应该会看到一个锯齿波形图,这些问题应该是显而易见的。每当图形下降,这就是GC插入,阻塞你的线程来清空我们的垃圾,这是与内存有关的主要原因冻结



锯齿波图例子蓝色图形是内存):



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

选项1:这通常是可以的,只需要考虑一下:闭包。您应尽量避免关闭,因为它们通常是GC的主要原因。



选项2:避免在户外参考你的范围,它没有帮助记忆的方式,它使你的应用程序有点慢,因为它必须在关闭链上找到匹配。这样做没有好处

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

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

 函数tmp(){
var a = 1;
删除一个; // false
console.log('a =',a)// 1

b = 2;
删除b; //真实的!
console.log('b =',b)//例外
}
tmp();

什么?!那么当你说 b = 2 (没有 var )时,与写 window.b = 2 所以当你是删除b 时,你基本上在做 delete window.b code>满足只删除属性条款。
然而,不要这样做!



选项5:这实际上为您节省了一小部分内存,因为它不需要GC x ,但是:它必须GC所有 x 的内容,这通常是很多大于 x 本身,因此它不会产生影响



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


I am currently building a game in Javascript. After some testing, I was beginning to notice occasional lag which could only be caused by the GC kicking in. II decided to run a profile on it. The result shows that the GC is in fact the culprit:

I read that creating new objects causes a lot of GC. I am wondering if something like this:

var x = [];

Creates any Garbage as well, since primitive types in Java don't do this. Since there are no real types in Javascript, I am unsure. Furthermore, which of these is the best for creating the least amount of garbage:

Option 1:

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

Option 2:

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

Option 3:

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

Or Option 4:

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

Option 5:

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

The do function is called 30 Times a Second in my case. And it runs several operations on the array.

I am wondering this, because I just made all of my variables global to try to prevent them from being collected by the GC, but the GC did not change much.

Could you also provide some common examples of things that create a lot of Garbage and some alternatives.

Thank you.

解决方案

Can you also show the memory of timeline? If you have GC issues those should be blatantly obvious there as you would see a sawtooth wave graph. Whenever the graph drops, that's the GC kicking in, blocking your thread to empty our the trash and that's the main cause of memory related freezing

Example of sawtooth wave graph (the blue graph is memory):

Generally speaking, which object instantiation do you use does not matter than much since the memory impact of a [] is minimal, what you're interested in is the content of the arrays, but to go through your options:

Option 1: This is generally OK, with one consideration: Closures. You should try to avoid closures as much as possible since they're generally the main cause for GC.

Option 2: Avoid referencing things outside of your scope, it doesn't help memory-wise and it makes your app a bit slower since it has to go up the closure chain to find the match. No benefit to doing this

Option 3: never ever do this, you always want to define x somewhere otherwise you're purposely leaking into the global scope and therefore it will potentially never be GCed

Option 4: This is actually an interesting one. normally delete x does not do anything since delete only acts on properties of an object. In case you didn't know, delete actually returns a boolean that signifies whether the object has been deleted or not, so you can run this example in the chrome console:

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

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

What the?! well when you say b = 2 (without the var) it's the same thing as writing window.b = 2 so when you're delete b, you're basically doing delete window.b which satisfy the "only delete property clause". Still, DON'T DO THIS!

Option 5: This one actually saves you a tiny tiny bit of memory since it doesn't have to GC x, HOWEVER: it does have to GC all the content of x which is generally much greater in size that x itself therefore it won't make a difference

This is a fantastic article if you want to learn more about memory profiling + common memory performance pitfalls: http://www.smashingmagazine.com/2012/11/writing-fast-memory-efficient-javascript/

这篇关于JavaScript垃圾收集。创建对象和变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆