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