ThreeJS garbage collection issue

2019-07-27 03:43发布

I have built a ThreeJS app using the canvas renderer (due to project requirements) that I've run into a memory/garbage collection issue with.

Part of the application logic creates a lot of meshes to achieve animations on segments of a flat 2d donut/ring. On each animation pass, we are removing all the previous meshes and generating new ones.

When objects are removed from the scene, they're not deleted from memory but instead, moved to an array called __objectsRemoved. This is kept around indefinitely - I imagine there is some kind of garbage collection that happens to clean everything up eventually but I don't know how to trigger that. The memory usage of the application continuously climbs until it grinds the browser to a halt within 30-40 seconds.

We have not been able to solve this issue and are desperately seeking advice. This project is due for launch for very soon so any immediate guidance/advice is greatly appreciated.

Here is a fiddle that illustrates the issue. http://jsfiddle.net/729sv/

var camera, scene, renderer;
var base = 0;

init();
animate();

function init() {
    renderer = new THREE.CanvasRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    scene = new THREE.Scene();

    camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000);
    camera.position.z = 100;

    document.addEventListener('mousedown', update, false);

    update();
}

function update() {

    if (base) scene.remove(base);

    base = new THREE.Object3D();
    scene.add(base);

    for (var j = 0; j < 10; ++j) {

        var geometry = new THREE.IcosahedronGeometry(50, 3);
        var material = new THREE.MeshNormalMaterial()
        var mesh = new THREE.Mesh(geometry, material);
        base.add(mesh);
    }
}

function animate() {
    requestAnimationFrame(animate);
    console.log(scene.__objectsRemoved.length);
    renderer.render(scene, camera);
}

We are running ThreeJS R62

Thank you!

1条回答
兄弟一词,经得起流年.
2楼-- · 2019-07-27 04:02

This is a bug in the library. Sorry about that :(

I can't believe we haven't hit this until now... __objectsAdded and __objectsRemoved were added for WebGLRenderer for performance reasons. However, we forgot about the side-effects this creates on other renderers (I see you're using CanvasRenderer...)

As a workaround... You can try overriding these arrays:

scene = new THREE.Scene();

if ( renderer instanceof THREE.CanvasRenderer ) {

    scene.__lights = { length: 0, push: function(){}, indexOf: function (){ return -1 }, splice: function(){} }
    scene.__objectsAdded = { length: 0, push: function(){}, indexOf: function (){ return -1 }, splice: function(){} }
    scene.__objectsRemoved = { length: 0, push: function(){}, indexOf: function (){ return -1 }, splice: function(){} }

}
查看更多
登录 后发表回答