为什么以下代码会分配大量内存?
Entity3D.prototype._updateEuler = function(elapsed) {
this.velocity.x += this.force.x / this.mass * elapsed;
this.velocity.y += this.force.y / this.mass * elapsed;
this.velocity.z += this.force.z / this.mass * elapsed;
var initialSpeed = this.speed = vector3.length(this.velocity);
if (this.speed && this.deceleration)
this.speed = Math.max(0, this.speed - this.deceleration*elapsed);
if (this.speed > this.maxSpeed)
this.speed = this.maxSpeed;
if (this.speed !== initialSpeed) {
this.velocity.x = this.velocity.x / initialSpeed * this.speed;
this.velocity.y = this.velocity.y / initialSpeed * this.speed;
this.velocity.z = this.velocity.z / initialSpeed * this.speed;
}
this.oldPosition.x = this.position.x;
this.oldPosition.y = this.position.y;
this.oldPosition.z = this.position.z;
this.position.x += this.velocity.x * elapsed;
this.position.y += this.velocity.y * elapsed;
this.position.z += this.velocity.z * elapsed;
if (this.speed > 0)
vector3.normalize(this.velocity, this.heading);
};
以上屏幕截图是以60 FPS运行游戏40秒后,每帧更新约200个Entity3D对象,在此期间_updateEuler()
被调用约500 000次。
上面代码中的所有属性都是常规数字或由对象文字创建的简单对象:{'x': 0, 'y': 0, 'z': 0}
并且它们是在创建对象时创建的,而不是每个帧。这意味着,上面的代码只是做了一些简单的数学运算并为属性分配数字。
Entity3D是一个表示某些游戏对象(包括粒子)的简单类。我在开始时分配了大约200个这些对象,并通过重置它们的属性而不是分配全新的实例来重用它们。
我是否正确读取了探查器,这个函数真的因某种原因分配了40 MB的RAM吗?
如何减少此功能的内存分配?
上述代码中使用的函数:
function normalize(vector, out) {
var l = Math.sqrt(vector.x*vector.x + vector.y*vector.y + vector.z*vector.z);
if (l > 0) {
out.x = vector.x / l;
out.y = vector.y / l;
out.z = vector.z / l;
} else
out.x = out.y = out.z = 0;
}
function length(vector) {
return Math.sqrt(vector.x*vector.x + vector.y*vector.y + vector.z*vector.z);
}
任何时候将浮点数分配给某个属性 对象或数组的元素,必须先装箱(分配在 堆)。如果你的程序执行了很多浮点数学, 拳击可能是昂贵的。使用对象时无法避免拳击 属性,但在数组上操作时,可以使用类型化数组 避免拳击。