2017-06-01 29 views
7

Şu anda ThreeJS uygulamamda belleği boş bırakmayla ilgili sorunlar yaşıyorum.ThreeJS uygulamasının belleğini boşaltma

Bu sorun hakkında zaten birçok sorular vardır farkındayım: Ben şu typescript kullanarak nesneleri elden yapmak

yaptığım işlev : Ben Chrome Dev Araçlarını kullanarak yığın anlık yaptığınızda

function dispose(object3D: THREE.Object3D): void 
{ 
    // Dispose children first 
    for (let childIndex = 0; childIndex < object3D.children.length; ++childIndex) 
    { 
     this.dispose(object3D.children[childIndex]); 
    } 

    object3D.children = []; 

    if (object3D instanceof THREE.Mesh) 
    { 
     // Geometry 
     object3D.geometry.dispose(); 

     // Material(s) 
     if (object3D.material instanceof THREE.MultiMaterial) 
     { 
      for (let matIndex = 0; matIndex < object3D.material.materials.length; ++matIndex) 
      { 
       object3D.material.materials[matIndex].dispose(); 
       object3D.material.materials[matIndex] = null; 
      } 
      object3D.material.materials = []; 
     } 

     if (object3D.material.dispose) 
     { 
      object3D.material.dispose(); 
      object3D.material = null; 
     } 
    } 

    // Remove from parent 
    if (object3D.parent) 
     object3D.parent.remove(object3D); 

    object3D = null; 
} 

Ancak, hala tonlarca vardır: (..., UVS __directGeometry olarak)

  • Vector2

    • Diziler
    • vector3 (faces normal geometry yılında köşe, faces yılında vertexColors, ...)
    • Face3 (geometry yüzleri)
    • Renk (__directGeometry renkler, ...)
    • JSArrayBufferData (geometry arasında attributes normal renk, ...) Çünkü bellekte tüm verilerin

    , başvurum tarafından öldürülmeden IOS'ta Jetsam, bkz .: Jetsam kills WebGL application on iOS

    Kütüphane içindeki bazı verilerin istenildiği zaman serbest kalmamasından şüpheleniyorum.

  • +1

    Daha çok Jetsam'ın aşırı derecede saldırgan olduğu gibi geliyor. JavaScript çöp toplanır, bu nedenle nesneler bırakıldıktan hemen sonra bir yığın anlık görüntü almak, GC'den sonra bellek durumunun ne olacağına% 100 yansıtmayabilir. Nesneler hiç gitmedi mi (1 dakika sonra)? Aksi takdirde, kodda kendilerine başka bir gönderme yapılmayabilir, çünkü serbest bırakılmamışsa, GC sadece bir nesneyi toplayabilir. – TheJim01

    +0

    Maalesef, 1 dakika sonra bile (hala GC uzun bir süre iş yapacağını düşündüm) bellekte hala görünüyor. '' Diğer sürümler, henüz çıkmamış olan koddaki diğer referanslar olabilir '', evet, bu, bu nesnelerin hafızadan silinmemesinin tek sebebidir. @ TheJim01: Kodda bir nesneyi "etiketlemenin" basit bir yolu varsa, Chrome Dev Tools'ta kolayca başvuruda bulunabilmem için nereden kaynaklandığını biliyor musunuz? – Hellium

    +0

    Ne yazık ki, referansları bulmak için kolay bir yol bilmiyorum. Eğer öğrenirsen, bana haber ver! Bunun dışında, problemi en basit biçimine indirgeyim: çok basit bir JavaScript-only uygulaması (No TypeScript) yazmak ve aynı şekilde çalışıp çalışmadığını görmek. Eğer yaparsa, başka ne yapabileceğinizden emin değilim. – TheJim01

    cevap

    0

    Sadece her şeyi atmaya çalışın. Bu snippet'i bir süredir kullanıyorum. Malzemeler, dokular, 3d nesneler içerir. Diziler ve düz nesneler üzerinde yineleme yapar.

    let dispose = function(o) { 
        try { 
         if (o && typeof o === 'object') { 
          if (Array.isArray(o)) { 
           o.forEach(dispose); 
          } else 
          if (o instanceof THREE.Object3D) { 
           dispose(o.geometry); 
           dispose(o.material); 
           if (o.parent) { 
            o.parent.remove(o); 
           } 
           dispose(o.children); 
          } else 
          if (o instanceof THREE.Geometry) { 
           o.dispose(); 
          } else 
          if (o instanceof THREE.Material) { 
           o.dispose(); 
           dispose(o.materials); 
           dispose(o.map); 
           dispose(o.lightMap); 
           dispose(o.bumpMap); 
           dispose(o.normalMap); 
           dispose(o.specularMap); 
           dispose(o.envMap); 
          } else 
          if (typeof o.dispose === 'function') { 
           o.dispose(); 
          } else { 
           Object.values(o).forEach(dispose); 
          } 
         } 
        } catch (error) { 
         console.log(error); 
        } 
    }; 
    
    +0

    r85 ile uyumlu değil – Displee

    İlgili konular