将文字/对象/类传递给具有数千个调用的函数的内存含义

时间:2014-12-09 00:12:55

标签: javascript memory

背景

我写的框架涉及Figure类,在SetTranslate( x, y )类上调用函数Renderer。反过来,Renderer类必须存储传递给(x, y)的参数SetTranslate

可能有数千个数字,因此单个用户操作可能会触发数千个这样的调用。

我有点担心使用对象或类的内存影响(以及垃圾收集代码)与此类调用的文字相比。

详情如下。

所有选项

相同

请原谅我在下面的代码中使用类类语法,但它对实际问题没有任何影响。人们可以轻松地用Class语法替换标准JS函数&原型语法。

在下面的所有选项中,图类使用属性rect构建,该属性是类Rect的新实例:

Figure = new Class({

    // Constructor 
    initialize: function() {
        this.rect = new Rect( 0, 0, 10, 10 );
    }    
});

选项1 - 使用原始值参数

图类:

Figure = new Class({
    render: function( aRenderer ) {
        aRenderer.setTranslate( this.rect.x, this.rect.y );
    }       
});

Renderer类:

Renderer = new Class({

    // Constructor 
    initialize: function() {
        this.translation = {
            x: 0,
            y: 0
        };
    },

    setTranslate: function( x, y ) {
        this.translation.x = x;
        this.translation.y = y;
    }       
});

关注

如果我没有弄错的话,这里没有内存分配,所以没有真正的顾虑 - 这很简单。

选项2 - 使用对象文字

图类:

Figure = new Class({    
    render: function( aRenderer ) {
        aRenderer.setTranslate( { x: this.rect.x, y: this.rect.y } );
    }       
});

Renderer类:

Renderer = new Class({

    // Constructor 
    initialize: function() {
        this.translation = {
            x: 0,
            y: 0
        };
    },

    setTranslate: function( aTranslation ) {
        this.translation = aTranslation;
    }       
});

关注

我的问题是如果使用

        aRenderer.setTranslate( { x: this.rect.x, y: this.rect.y } );

创建一个新对象。此外,通过执行

        this.translation = aTranslation;

以前的对象现在不会进入垃圾收集吗?

选项3 - 使用类实例

图类:

Figure = new Class({    
    render: function( aRenderer ) {
        // rect.getTopLeft() returns new Point( x, y );
        aRenderer.setTranslate( this.rect.getTopLeft() );
    }       
});

Renderer类:

Renderer = new Class({

    // Constructor 
    initialize: function() {
        this.translation = new Point( 0, 0 );
    },

    setTranslate: function( aTranslation ) {
        this.translation = aTranslation;
    }       
});

关注

getTopLeft()返回new Point( x, y )这一事实明确了内存分配将成为其中的一部分:

        // rect.getTopLeft() returns new Point( x, y );
        aRenderer.setTranslate( this.rect.getTopLeft() );

很明显,这一行:

        this.translation = aTranslation;

上一个translation对象(类)将进入垃圾收集。

这与选项2有什么不同?

因为这对我来说是理想的解决方案(Point类有可能对setTranslate内的其他内容有用的方法),如果每个用户操作可能有数千个这样的调用,那么它会成为一个问题(与选项1和2相比,即)?

1 个答案:

答案 0 :(得分:1)

我认为您会发现对象池是控制此类内存行为的一种非常有效的方法。预先分配您需要的对象数量,然后重复使用它们以避免垃圾收集问题。

要回答你的问题,

aRenderer.setTranslate( { x: this.rect.x, y: this.rect.y } );

将创建一个新对象,是的,在您的示例中,前一个转换对象符合GC条件(假设没有其他引用)。