2017-06-01 33 views
7

Mam obecnie problemy z zwalnianiem pamięci w mojej aplikacji ThreeJS.Zwalnianie pamięci aplikacji ThreeJS

Jestem świadomy istnieje już kilka pytań dotyczących tego problemu:

robię wyrzucać moje obiekty przy użyciu następujące maszynopis funkcja, którą stworzyłem :

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; 
} 

Jednak, kiedy zrobić zrzuty sterty używając Chrome Dev Narzędzia, nadal mam tony i tony:

  • tablic
  • Vector2 (UVS w __directGeometry ...)
  • Vector3 (wierzchołki w geometry, normalne w faces, vertexColors w faces, ...)
  • Face3 (twarze w geometry)
  • Kolor (kolory w __directGeometry, ...)
  • JSArrayBufferData (kolor, normalna, w attributes z geometry ...)

Ze wszystkich danych w pamięci, moja aplikacja zostanie zabity przez Jetsam na iOS, patrz: Jetsam kills WebGL application on iOS

Podejrzewam, że niektóre dane w bibliotece nie są zwalniane, gdy o to poproszę.

+1

To brzmi bardziej jak Jetsam jest zbyt agresywny. JavaScript jest zbierany śmieci, więc zrobienie migawki sterty natychmiast po zwolnieniu obiektów może nie odzwierciedlać w 100% stanu pamięci po GC. Czy obiekty kiedykolwiek znikają (jak po 1 minucie)? Jeśli nie, to mogą istnieć inne odniesienia do nich w kodzie, które nie zostały zwolnione, ponieważ GC może jedynie zbierać obiekt, jeśli nic go nie odwołuje. – TheJim01

+0

Niestety, wydaje się, że wciąż są w pamięci, nawet po 1 minucie (co jest dość długim czasem, myślałem, że GC będzie wykonywać swoją pracę częściej). W kodzie, które nie zostały wydane, mogą znajdować się inne odniesienia do nich, _ tak, to jedyny powód, dla którego obiekty te nie zostałyby usunięte z pamięci. @ TheJim01: Czy wiesz, czy istnieje "prosty" sposób na "tagowanie" obiektu w kodzie, aby go łatwo pobrać z Narzędzi dewelopera Chrome, dzięki czemu mogę zobaczyć, gdzie się on znajduje? – Hellium

+0

Niestety, nie znam żadnego łatwego sposobu na znalezienie referencji. Jeśli się dowiesz, daj mi znać! :) Poza tym ograniczyłbym problem do jego najprostszej postaci: napisz bardzo prostą aplikację tylko JavaScript (bez TypeScript) i sprawdź, czy działa w ten sam sposób. Jeśli tak, to nie jestem pewien, co jeszcze możesz zrobić. – TheJim01

Odpowiedz

0

Spróbuj pozbyć się wszystkiego. Używam tego fragmentu przez jakiś czas. Zbiera materiały, tekstury, obiekty 3D. Iteruje nad tablicami i zwykłymi obiektami.

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

niezgodny z r85 – Displee

Powiązane problemy