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!
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 forWebGLRenderer
for performance reasons. However, we forgot about the side-effects this creates on other renderers (I see you're usingCanvasRenderer
...)As a workaround... You can try overriding these arrays: