最佳实践threejs几何处理?

时间:2018-03-07 03:21:24

标签: three.js

如果我有以下内容:

myObj = new THREE.Object3d;
scene.add(myObj);    
doIt();

function doIt(){
  var geometry = new THREE.SphereGeometry( 1, 8, 8 );
  var mesh = new THREE.Mesh( geometry, meshMaterial );
  myObj.add(mesh);
}

据我所知,变量geometrymesh在函数结束后立即取消分配。但是scene对象仍然包含myObj,它仍然包含网格,它仍包含几何体。现在,几何图形位于myObjscene内。我到目前为止做得对吗?

但如果我那么做

scene.remove(myObj);

以及

myObj = new Object();

然后我会认为没有更多的网格,没有更多的几何。我不再拥有包含或引用这些东西的任何现存变量或对象。但它们仍然存在于某处,占据记忆?

在three.js中有一个dispose()函数,但我不明白我的代码序列应该在哪里正常应用,或者究竟是为什么?

我正在开发一个需要创建然后删除大量对象的项目,所以我担心如果我做得不对,就会出现性能问题。

任何智慧都非常赞赏。

1 个答案:

答案 0 :(得分:1)

在javascript中,对象存在于内存中,直到它们被垃圾收集器清除。通过为变量分配新对象,您基本上只是创建一个具有相同名称的新变量。旧数据仍然存在于内存中,直到垃圾收集器运行并从内存中删除旧数据。

由于JavaScript的内存只能被垃圾收集器清除,并且你无法手动触发垃圾收集(而且你不应该),你应该使用对象汇集而不是创造大量的一次性物品。

注意:这并不意味着总是使用对象池,而是 您会发现自己在短时间内创建和解除引用大量对象 请记住,不要过早优化。

  

简单来说,对象池是保留一组共享类型的未使用对象的过程。当您需要为代码创建新对象时,而不是从系统内存堆中分配新对象,而是从池中回收其中一个未使用的对象。一旦外部代码完成对象,而不是将其释放到主内存,它将返回到池中。因为对象永远不会从代码中解除引用(也就是删除),所以它不会被垃圾回收。 利用对象池将内存控制权交还给程序员,减少了垃圾收集器对性能的影响。

source

您可以在线找到各种对象池样板,但这里有一个示例:https://gist.github.com/louisstow/5609992

注意:如果您不再创建大量对象,则没有理由在内存中保留大量多余的对象。您应该减小池大小,释放未使用的对象,并允许GC收集它们。如果需要,您可以随时再次增加尺寸。只是不要在缩小和快速增加池大小之间切换,否则你只会击败对象池的点。

var objectPool = [];
var marker = 0;
var poolSize = 0;

//any old JavaScript object
function commonObject () { }

commonObject.create = function () {
    if (marker >= poolSize) {
        commonObject.expandPool(poolSize * 2);
    }

    var obj = objectPool[marker++];
    obj.index = marker - 1;
    obj.constructor.apply(obj, arguments);
    return obj;
}

//push new objects onto the pool
commonObject.expandPool = function (newSize) {
    for (var i = 0; i < newSize - poolSize; ++i) {
        objectPool.push(new commonObject());
    }

    poolSize = newSize;
}

//swap it with the last available object
commonObject.prototype.destroy = function () {
    marker--;
    var end = objectPool[marker];
    var endIndex = end.index;

    objectPool[marker] = this;
    objectPool[this.index] = end;

    end.index = this.index;
    this.index = endIndex;
}

//make this as big as you think you need
commonObject.expandPool(1000);