Optimizing Memory Usage in Three.js: Properly Disposing of Scenes

I am encountering numerous challenges in eliminating memory leaks while utilizing three.js within a reactive application. After investigating, I discovered that even disposing of a scene correctly (without rendering) poses difficulties. Allow me to demonstrate:

https://plnkr.co/edit/Z0sXOnXYc2XOV4t9tETv

In the above example, initially, 3 THREE objects are instantiated (no rendering, just object instantiation):

  • scene
  • camera
  • renderer

By utilizing Chrome DevTools, let's capture a memory snapshot immediately after loading the page:

https://i.sstatic.net/SbQ7j.png

Now, let's click on the "ADD 1000 MESHES" button, which essentially creates 1000 meshes (BoxGeometry + MeshBasicMaterial) and adds them to the scene object. After taking another memory snapshot, we can compare it with the previous one:

https://i.sstatic.net/osroc.png

As observed, our memory usage increased from 25.2 Mb to 36.2 Mb, with an additional +1000 Mesh objects stored in memory.

Next, by clicking the "DISPOSE" button, we execute the following dispose function:

 const dispose = (e) => {           

    // dispose geometries and materials in scene
    sceneTraverse(scene, o => {

        if (o.geometry) {
            o.geometry.dispose()
            console.log("dispose geometry ", o.geometry)                        
        }

        if (o.material) {
            if (o.material.length) {
                for (let i = 0; i < o.material.length; ++i) {
                    o.material[i].dispose()
                    console.log("dispose material ", o.material[i])                                
                }
            }
            else {
                o.material.dispose()
                console.log("dispose material ", o.material)                            
            }
        }
    })          

    scene = null
    camera = null
    renderer && renderer.renderLists.dispose()
    renderer = null

    addBtn.removeEventListener("click", addMeshes)
    disposeBtn.removeEventListener("click", dispose)

    console.log("Dispose!")
}

This function traverses through the scene, disposing of every geometry and material. The references to scene, camera, and renderer are set to null, and listeners are removed to prevent memory leaks. Upon clicking the DISPOSE button and capturing a new memory snapshot, my expectation was that the garbage collector would clear all data related to the 1000 Meshes (Mesh, Matrix4, Vector3, BoxGeometry, etc…). However, the reality proved to be quite different:

https://i.sstatic.net/flRvt.png

Although it appears that 1000 Mesh objects were deleted, the memory usage remains nearly identical to the previous snapshot (34.6 vs 36.2 Mb). While there are drops in Vector3, Matrix4, Quaternion, and Euler objects, most objects persist in memory and avoid being collected by the garbage collector. In fact, comparing snapshots 3 and 1 confirms this:

https://i.sstatic.net/gvD4f.png

If possible, could someone elaborate on what is happening and provide guidance on correctly disposing of elements in three.js?

Three.js: 102 Google Chrome: 72.0.3626.121 (64-bit)

Answer №1

The issue at hand was caused by the console.log statements, as they were preventing the garbage collection of the objects being printed on the Chrome console. By removing these console.log statements, the problem was successfully resolved.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I have a project where I'm tasked with assembling a collection of images sourced from an Array populated with JSON

For a homework assignment, I am tasked with creating a basic gallery that showcases 4 images. My goal is to store all the images in an array, with each photo represented as a JSON object, and then load these images from the array. Here is my progress so fa ...

Creating a dynamic two-player chess application using Django - requiring the player's chess board to automatically update whenever the opponent makes a move

I am looking for a solution where each player has their own webpage equipped with a Javascript chessboard GUI interface that allows them to click and drag pieces. The challenge is ensuring that when one player makes a move, the other player's chessboa ...

Combining all elements of my application into a single HTML, JS, and CSS file

My AngularJS app has a specific structure that includes different directories for each component: theprojectroot |- src | |- app | | |- index.html | | |- index.js | | |- userhome | | | |- userhome.html | | | ...

Populating a Listview in jqueryMobile with dynamic elements

I am struggling with my listview. Whenever I try to add or remove items from the list, the jquery mobile styling does not get applied to the new content that is added. <ul data-role="listview" id="contributionList"> <li id="l1"><a>5. ...

Why does this reduce operation seem to be altering the original array?

My goal is to condense the items array to only have one element for "apple" with an updated quantity value. The code snippet below successfully achieves this, but it unexpectedly alters the original items array as well. I'm puzzled by this behavior an ...

instructions on how to exclusively close a bracket within a double bracket in a regular expression match

const input = "example(1)(2)example(3)example(4)(5)example(6)(7)example(8)example(9)" const regexp = new RegExp(????) // <-- need help with this input.match(regexp) result: [example(1)(2), example(3), example(4)(5), example(6)(7), example(8), example( ...

Loading images from Contentful in Angular 8 using Resolve before rendering them on the view

I am currently facing a challenge that I need help with: https://i.sstatic.net/ytLoj.gif The issue I am encountering is that when the page loads, the view renders before the images fully load. Is there a way to ensure that the view only renders once the ...

Can you explain the distinction between using "require" to return a module and accessing the actual object in node.js?

When working with node.js, the commonly used method to include modules from other files is by using "require", whether it's from our own code or third-party libraries. But for me, there seems to be some confusion regarding the distinction between the ...

The page's layout becomes disrupted when the back end is activated, requiring some time to realign all controls

I recently set up a website and I am facing an issue where certain pages shake uncontrollably when buttons are clicked. The problematic page can be found at the following link: Specifically, when trying to click on the "SEND OFFER" button, the entire pag ...

Tips on displaying various colors in selected HTML elements by adding them to an array and showcasing them in a unique way. Issue arises when colors are displayed multiple times upon appending

javascript function fetchc(){ pclr=document.getElementById("product_color").value; clr.push(pclr); var n=clr.length; $("#colors").show(); for (var i=0;i<n;i++) { $("#colors").append('<input type="color" value="'+clr[i]+'" disabled& ...

Why should you use memcached with node.js?

As part of my project to create a straightforward login system, I need to manage two cookies. One will identify the logged-in user while the other will specify the "plan" (database) that the user is associated with. For security reasons, both cookies (us_a ...

Ways to enhance the value of an option within a drop-down menu in angular js 1.x and retrieve the selected value

Can someone help me convert this jQuery code to AngularJS 1.x? <select id="select"> <option value="1" data-foo="dogs">this</option> <option value="2" data-foo="cats">that</option> <option value="3" data-foo="gerbil ...

In my experience with Laravel, I discovered that all the buttons within a form were posting to the same URL after experimenting with Ajax

Facing an issue after attempting to incorporate ajax post in Laravel. Now, all my buttons with type submit are posting to the same route, even if they had no functionality previously. Additionally, a cancel button that used to redirect to the previous scre ...

Iterating through a dataset in JavaScript

Trying to find specific information on this particular problem has proven challenging, so I figured I would seek assistance here instead. I have a desire to create an arc between an origin and destination based on given longitude and latitude coordinates. ...

Angular form not processing unless all mandatory fields are completed

I am currently working on building a form using Angular and Ionic. I want to ensure that the red error class is only displayed after the user has submitted the form. To achieve this, my code is structured as follows: <form ng-submit="submit()" name="fo ...

Tips for pulling out a specific section of text from a string using various values in JavaScript

I have a block of text containing a mix of emails, phone numbers, and URLs that I need to extract individually. I attempted to use a substring method in JavaScript to achieve this, but I seem to be encountering some challenges. Below is a snippet of the ...

Node.js encounters issue with undefined parameters in receiving multiple messages

Currently, I am attempting to upload 2 files to my node.js server using multer to receive the data from the request. Below is the endpoint setup: app.post('/testFile', imageUpload.fields([{name:'image',maxCount:1},{name:'i ...

Filtering in JavaScript can be efficiently done by checking for multiple values and only including them if they are not

In my current coding challenge, I am attempting to create a filter that considers multiple values and only acts on them if they are not empty. Take the following example: jobsTracked = [ { "company": "Company1", ...

Issue with storing callback in parent component state leading to a stale closure situation

I've encountered a situation where I need to register a function in the state of my parent component. This function captures some local state within the child component. However, there is an issue where the function always retrieves an outdated value ...

Animating text with a shake effect using JQuery

I am attempting to create a shake effect on my text input field when validation fails. While I have achieved the shake effect, I am unsure how to customize the default values for direction, distance, and times. Additionally, I believe there is an error i ...