atteneder / glTFast

Efficient glTF 3D import / export package for Unity
Other
1.24k stars 251 forks source link

Memory Leak: Unable to completely remove a run-time loaded GLB from memory #726

Open Tom-Render opened 1 week ago

Tom-Render commented 1 week ago

First, thanks for the magnificent codebase šŸ˜‰, this issue has me completely stumped so Iā€™m pretty confident itā€™s a bug. However, apologies in advance if itā€™s not and thereā€™s some elusive means of clearing gLTFastā€™s memory use Iā€™ve somehow missed in the included example project.

Describe the bug

Every time we load a new GLB model we can only partially remove it from memory. This seems to happen on every platform, but is particularly problematic for us on iPad, where our application will inevitably build up memory use over time and eventually crash. To clarify, each one of our models is optimised enough to be viewed individually but viewing them in sequence causes issues because we cannot completely remove their predecessors from RAM.

Files

A small example unity project (including a glb) which re-creates the issue and produces .snap files (unity memory snapshots) as evidence can be downloaded here: https://we.tl/t-jYf1k8LwRZ

To Reproduce

  1. Download the example project: https://we.tl/t-jYf1k8LwRZ
  2. Extract and open it in Unity 2022.3.51f1
  3. Open build settings and tick ā€œDevelopment Buildā€, then do a build
  4. Run the built executable, the example application will:
    1. Load an empty scene, then take a first memory snapshot.
    2. Additively load a new scene.
    3. Run-time load a glb inside of that new scene.
    4. Destroy the loaded glb and clear any references to it.
    5. Unload the scene the glb (and the script that loaded it) was in.
    6. Force a memory clean-up with Resources/UnloadUnusedAsset and GC.Collect.
    7. Take a second memory snapshot
  5. Wait until the application says, ā€œDemonstration completeā€. You can then close the application.
  6. There will be two new .snap files on your desktop, return to the Unity Editor and use Window -> Analysis -> Memory Profiler to import and compare the .snap files. For example, I get an additional 270mb of untracked memory from the second memory snapshot, when ideally both snap files would have the same memory use.

Expected behaviour

When the first and second memory snapshots are compared, memory usage should be nearly identical. We should be able to restore RAM usage to (roughly) the original amount it was before the GLB was loaded.

Screenshots

Capture

Desktop (please complete the following information):

Tom-Render commented 3 days ago

I realised my example above, crucially, doesnā€™t invoke GltfImport.Dispose, hereā€™s a version of the project which does invoke GltfImport.Dispose: https://we.tl/t-dzLqJbvrGf

Sadly, the memory leak is still present even after invoking GltfImport.Dispose:

Capture

Tom-Render commented 3 days ago

For the sake of completeness, I should also note that I've now tested the example project in Unity 6000.0.25f1 and the leak still occurs.