ArrayBuffers (normal and position ArrayBuffers of BufferGeometry object) are not released from the memory when the object is loaded on a web worker and transferred to the main thread.
//main thread
// This is the similiar code that I have
var mesh, renderer, scene, camera, controls;
var models =[];
var loaded_object;
var worker = undefined;
init();
animate();
function init() {
// renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
// scene
scene = new THREE.Scene();
// camera
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set( 20, 20, 20 );
// controls
controls = new THREE.OrbitControls( camera );
// ambient
scene.add( new THREE.AmbientLight( 0x222222 ) );
// light
var light = new THREE.DirectionalLight( 0xffffff, 1 );
light.position.set( 20, 20, 0 );
scene.add( light );
// axes
scene.add( new THREE.AxesHelper( 20 ) );
// geometry
var geometry = new THREE.SphereGeometry( 5, 12, 8 );
// material
var material = new THREE.MeshLambertMaterial({
color: 0x99C9E9,
overdraw: 1,
wireframe: false,
vertexColors: THREE.FaceColors
});
// mesh
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
}
function animate() {
requestAnimationFrame( animate );
//controls.update();
renderer.render( scene, camera );
}
var worker = undefined;
document.getElementById('upload_model_btn').onclick =function(){
//...
worker = new Worker('upload_model.js');
worker.addEventListener('message',display_model,false)
worker.postMessage('message',model_filepath);
}
function display_model(event){
//e.data.normal is the arraybuffer of the loaded object which was tranferred from the worker.
var main_normal= new Float32Array(new ArrayBuffer(e.data.normal.byteLength));
main_normal.set(new Float32Array(e.data.normal));
var main_position = new Float32Array(new ArrayBuffer(e.data.position.byteLength));
main_position.set(new Float32Array(e.data.position));
worker_position = null;
worker_normal = null;
var bufferGeometry = new THREE.BufferGeometry();
bufferGeometry.addAttribute('position',new THREE.BufferAttribute(main_position,3));
bufferGeometry.addAttribute('normal',new THREE.BufferAttribute(main_normal,3));
loaded_object = new THREE.Mesh(bufferGeometry,material);
main_position = null;
main_normal = null;
delete e.data.normal;
delete e.data.position;
bufferGeometry.dispose();
bufferGeometry = null;
scene.add(loaded_object);
worker.removeEventListener('message',display_model);
worker.terminate()
worker = undefined;
}
//when I delete the model, I have:
function delete_loaded_object(){
scene.remove(loaded_object);
loaded_object.geometry.dispose();
loaded_object.geometry = null;
loaded_object.material.dispose();
loaded_object.material = null
renderer.renderLists.dispose();
loaded_object = null;
}
//upload_model.js web worker.
var loader = new THREE.STLLoader();
var transfer_list={}
self.addEventListener('message', function(e) {
loader.load(e.data.filepath, (bufferGeometry)=>{
transfer_list.normal = bufferGeometry.getAttribute('normal').array.buffer,
transfer_list.position = bufferGeometry.getAttribute('position').array.buffer
// bufferGeometry.dispose();
// bufferGeometry = null;
self.postMessage(transfer_list,[transfer_list.normal,transfer_list.position]);
transfer_list = null;
});
}, false);
When I look up the memory after the deletion of the object, the difference before the object was loaded and after it was deleted is exactly the total amount of bytes of position and normal ArrayBuffers that I have.
Moreover, the only way to release this amount of memory is if I explicitly invoke the garbage collector of Chrome browser. I am not sure if there’s something wrong with my code or if there’s a bug on the three.js library because clearly the objects are not being disposed.
Thank you and I do apologize for the formatting and if I was not clear enough describing the problem.