मुझे अपने ऐप में वीआरएएम मेमोरी लीक का सामना करना पड़ा है। ऐप वॉल्यूमेट्रिक एनिमेशन बनाने के लिए THREE.Geometry को अक्सर जोड़ता और हटाता है। यदि THREE.Geometry के बजाय इसके स्वयं के आबादी वाले कोने के साथ, मैंने इसके बजाय THREE.SphereBufferGeometry का उपयोग किया, तो स्मृति रिसाव नहीं होता है।

मैंने यह साबित करने के लिए एक न्यूनतम ऐप बनाया है कि यह मेमोरी लीक असली है। मेमोरी लीक वीआरएएम मेमोरी को बहुत धीरे-धीरे बढ़ाता है, लेकिन यह अंत में भर जाता है। मुझे लगता है कि पूल मदद नहीं करेंगे, क्योंकि यह वीआरएएम है और प्रबंधित मेमोरी नहीं है। मैं निपटान का उपयोग करता हूं।

यदि आप यह नमूना काम कर सकते हैं और स्मृति रिसाव नहीं है, तो इससे मेरी समस्या हल हो सकती है:

https://jsfiddle.net/4a7ksryd/16/

संपादित करें: मैं यहां ऐप का कोड जोड़ रहा हूं:

var camera, scene, renderer;
var geometry, material, mesh;
var lastSphere;
var lastGeo;

init();
animate();

function init() {

    camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
    camera.position.z = 1;

    scene = new THREE.Scene();


    renderer = new THREE.WebGLRenderer( { antialias: true } );
    renderer.setSize( window.innerWidth, window.innerHeight );
    renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap

    var light = new THREE.DirectionalLight( 0xffffff, 1, 100 );
light.position.set( 0, 4, 0 );          //default; light shining from top
light.castShadow = true;            // default false
//Set up shadow properties for the light
light.shadow.mapSize.width = 1024;  // default
light.shadow.mapSize.height = 1024; // default
light.shadow.camera.near = 1;    // default
light.shadow.camera.far = 20;     // default

scene.add( light );


    //Create a sphere that cast shadows (but does not receive them)

geometry = new THREE.SphereBufferGeometry( 0.1, 32, 32 );
material = new THREE.MeshStandardMaterial( { color: 0xff0000 } );
//    geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
//    material = new THREE.MeshNormalMaterial();

    mesh = new THREE.Mesh( geometry, material );
    mesh.position.y = 0.1;
    mesh.castShadows = true;
    mesh.receiveShadow = false;
    scene.add( mesh );

    var planeGeometry = new THREE.PlaneBufferGeometry( 15, 15, 1, 1 );
var planeMaterial = new THREE.MeshStandardMaterial( { color: 0xffffff, emissive:0x111111 } )
var plane = new THREE.Mesh( planeGeometry, planeMaterial );
plane.position.y = -0.2;
plane.rotation.x = -Math.PI / 2;
plane.receiveShadow = true;
scene.add( plane );


    document.body.appendChild( renderer.domElement );

}

function animate() {

    requestAnimationFrame( animate );

    mesh.rotation.x += 0.01;
    mesh.rotation.y += 0.02;

        var dim = 32;
        var geo1 = new THREE.Geometry();
    const numVertices = dim*dim;
    var vertices = new Array(numVertices);
    for (var i=0; i<vertices.length; i++)
    {
        const x = i%dim;
        const y = (Math.floor(i/dim))%dim;    
      vertices[i] = new THREE.Vector3(x*0.1, y*0.1, 0);
    }
    const numFaces = (dim-1)*(dim-1)*2;
    var faces = new Array(numFaces);

    for (var i=0; i<(faces.length/2); i++)
    {
        const x = i%(dim-1);
        const y = Math.floor(i/(dim-1))%(dim-1);
        faces[2*i] = new THREE.Face3(x+y*dim, x+1+y*dim, x+(y+1)*dim);
        faces[2*i+1] = new THREE.Face3(x+1+y*dim, x+1+(y+1)*dim, x+(y+1)*dim);
    }
    var uv = new Array(numFaces);
    for (var i=0; i<uv.length; i++)    
        uv[i] = [new THREE.Vector2(0, 0), new THREE.Vector2(0, 0), new THREE.Vector2(0, 0)];
    geo1.faces = faces;
    geo1.vertices = vertices;
    geo1.faceVertexUvs[0] = uv;
        geo1.uvsNeedUpdate = true;
        geo1.verticesNeedUpdate = true;
        geo1.elementsNeedUpdate = true;
//    var sphereGeometry = new THREE.SphereBufferGeometry( 0.1, 256, 256 );
    var sphereGeometry = geo1;
    var sphereMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
    var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial );
    sphere.position.y = 0.1+Math.sin(mesh.rotation.x)*0.1;
    sphere.position.x = 0.5;
    sphere.castShadow = true; //default is false
    sphere.receiveShadow = false; //default
    if (lastGeo!=null)
        lastGeo.dispose();
    if (lastSphere!=null)
        scene.remove(lastSphere);
    scene.add( sphere );
    lastSphere = sphere;
    lastGeo = sphereGeometry;
//    geo1.dispose();

    renderer.render( scene, camera );

}
2
ofer rubinstein 8 अक्टूबर 2020, 13:49

1 उत्तर

सबसे बढ़िया उत्तर

यह वास्तव में three.js में एक बग है। मैंने इस मुद्दे को ठीक करने के लिए एक पीआर दायर किया है:

https://github.com/mrdoob/three.js/pull/20479

4
Mugen87 8 अक्टूबर 2020, 15:37