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

Javascript 将文字/对象/类传递给具有数千个调用的函数的内存含义 背景,javascript,memory,Javascript,Memory,我正在编写的一个框架涉及一个Figure类在渲染器上调用函数SetTranslate(x,y)。反过来,Renderer类必须存储传递给SetTranslate的参数(x,y) 可能有数千个数字,因此单个用户操作可能会触发数千个此类呼叫。 与此类调用的文本相比,我有点担心使用对象或类的内存影响(和垃圾收集影响) 具体内容如下 所有选项都相同 请原谅我在下面的代码中使用类语法,但这与实际问题没有区别。可以很容易地用标准JS函数和原型语法替换类语法 在下面的所有选项中,地物类使用属性rect构造,该

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

可能有数千个数字,因此单个用户操作可能会触发数千个此类呼叫。

与此类调用的文本相比,我有点担心使用对象或类的内存影响(和垃圾收集影响)

具体内容如下

所有选项都相同 请原谅我在下面的代码中使用类语法,但这与实际问题没有区别。可以很容易地用标准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 );
    }       
});
Figure = new Class({    
    render: function( aRenderer ) {
        aRenderer.setTranslate( { x: this.rect.x, y: this.rect.y } );
    }       
});
Figure = new Class({    
    render: function( aRenderer ) {
        // rect.getTopLeft() returns new Point( x, y );
        aRenderer.setTranslate( this.rect.getTopLeft() );
    }       
});
渲染器类:

Renderer = new Class({

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

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

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

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

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

    setTranslate: function( aTranslation ) {
        this.translation = aTranslation;
    }       
});
担心 如果我没有弄错的话,这里不涉及内存分配,所以没有真正的问题——这很简单

选项2-使用对象文字 图形类:

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

Renderer = new Class({

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

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

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

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

    // Constructor 
    initialize: function() {
        this.translation = new Point( 0, 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 ) {
        aRenderer.setTranslate( this.rect.x, this.rect.y );
    }       
});
Figure = new Class({    
    render: function( aRenderer ) {
        aRenderer.setTranslate( { x: this.rect.x, y: this.rect.y } );
    }       
});
Figure = new Class({    
    render: function( aRenderer ) {
        // rect.getTopLeft() returns new Point( x, y );
        aRenderer.setTranslate( this.rect.getTopLeft() );
    }       
});
渲染器类:

Renderer = new Class({

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

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

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

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

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

    setTranslate: function( aTranslation ) {
        this.translation = aTranslation;
    }       
});
担心
gettoplft()
返回一个
新点(x,y)
这一事实明确表明内存分配将是其中的一部分:

        // rect.getTopLeft() returns new Point( x, y );
        aRenderer.setTranslate( this.rect.getTopLeft() );
很明显,有了这句话:

        this.translation = aTranslation;
上一个
转换
对象(类)将进入垃圾收集

这与选项2有什么不同吗


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

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

回答你的问题,

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

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

option1的setTranslate()可能会使用最少的ram,因为它不会创建新对象。如果您真的非常喜欢内存消耗,您只需传递对
this.rect
的引用,它已经是一个具有
x
y
属性的对象:-)但是,这将是一个肮脏的设计,可能对非矩形不起作用。@Bergi
this.rect
实际上是
this.bounds
,所有图形都有(甚至是
Circle
Line
-图
的后代)。这是一个真正的问题,
Figure
有一个方法
getBounds
;对于一些图,这只是返回
this.bounds
,但对于其他图(就像一条线,由
fromPoint
和'toPoint'定义-这是动态计算的。所以我可以让所有的图形都有
这个。边界
;为动态计算的图形更新它,并返回它。但困扰我的主要问题是-我应该关心吗?所以GC中有5000个对象。性能/内存方面,wh惩罚是什么?我问这个问题是因为当内存越来越大,处理器越来越快时,代码是唯一保持静态的东西。所以我认为人们应该总是优先考虑代码质量而不是内存和性能。那么5000个GC对象有多糟糕?我想这是一个单独的问题。是的,你应该首先选择干净的代码。如果你有性能性能问题,然后你会去调查主要问题并解决它。5000个对象是否足够取决于环境,以及测量的时间范围。我不认为为
建立对象池会比他的选项1更好-无论如何每个渲染器只有一个翻译。