Skip to main content

🧠 Memory

Introduction#

πŸ“­πŸ“« On many occasions we will want to create applications that are able to open and close BIM viewers. Although this may seem obvious, there is a problem: memory management.

πŸ€” Now many will be scratching their heads, since memory management is not a common issue in web applications. JavaScript and other modern languages have automatic memory management / garbage collector, so the programmer doesn't have to worry about freeing up objects and arrays.

βœπŸ€–β“ However, when working with Three.js, data going to the graphics card (e.g. buffers) is not affected by this automatic memory management.

πŸ€• That means that if we close a viewer made with Three.js (with or without IFC.js), we will create a πŸ’¦ memory leak πŸ’¦. That is to say, we are blocking a part of the user's RAM memory. If the leak becomes too big, the application will become slower and slower and may crash.

πŸš€ This becomes especially critical if we are creating a SPA (Single Page Application), for example, using frameworks and libraries such as React or Angular**. In these cases the web application is never reloaded, and the memory leak accumulates.

Fortunately, IFC.js has taken this into account and allows you to release the used memory very easily. Let's see how. πŸ‘‡

You can find the full example of this tutorial here.

How to do it#

Monitoring the memory#

πŸ‘€ The first question you probably have if you haven't worked much with Three.js optimized scenes is how to see how much memory your application consumes. Otherwise, it is impossible to detect memory leaks.

🌍 There are several ways to do this. The first is to use the developer tools of the browser you are using. For example, in Google Chrome there is a section called "Memory" where you can take snapshots and see how much memory the current tab is consuming.

πŸ€– However, a more convenient way is to use the library stats.js. This library allows to monitor the performance and memory of a Three.js application. It can be installed with npm i stats.js and can be used as follows:

// Stats
const stats = new Stats();
stats.showPanel(2);
document.body.append(stats.dom);
// Animation loop
const animate = () => {
stats.begin();
// Update other stuff
stats.end();
requestAnimationFrame(animate);
};
animate();

πŸ“‹ This will bring up the scene statistics during execution. By clicking on them we can toggle between performance and memory usage of the app.

Dispose memory#

✌ Now let's create a function that removes all the memory consumed by IFC.js. There are 2 things to keep in mind:

  • If we have specified the path to the WASM files previously, we will have to do it again in the new instance of web-ifc-three.

  • This one is important: if we have stored a reference to the loaded IFC models in an array, an object or a class, we have to delete them manually. Otherwise, the memory will not be freed.

async function releaseMemory() {
// This releases all IFCLoader memory
await ifcLoader.ifcManager.dispose();
ifcLoader = null;
ifcLoader = new IFCLoader();
// If the wasm path was set before, we need to reset it
await ifcLoader.ifcManager.setWasmPath("../../../");
// If IFC models are an array or object,
// you must release them there as well
// Otherwise, they won't be garbage collected
models.length = 0;
}

Set up simple GUI#

πŸ’… Finally, we are going to create an HTML button and link it to the function we created earlier.

<input type="button" id="memory-button" value="Release memory" />
// Sets up memory disposal
const button = document.getElementById("memory-button");
button.addEventListener(`click`, () => releaseMemory());

😎 This is how the application looks like:

Try loading a model and releasing the memory: you'll see it go back to normal. Beware that it can take some seconds, as the browser garbage collector takes some time. Alternatively, you can manually apply the garbage collector using the browser's developer tools.

SPA#

🌈 It is very common to create SPA or Single Page Applications because they are more efficient and require less communication with the backend. Examples of tools to make these applications are React, Angular, Vue, etc.

πŸ‘ΆπŸ‘΄ In many cases these tools manage the lifecycle of the application components automatically. For example, when the user closes the 3d view, the HTML element containing the view is automatically destroyed.

🚧🚧🚧 To avoid memory leaks, it will be necessary to free the application memory as seen in this tutorial each time the component containing the 3D view is destroyed. In many cases there are hooks or similar mechanisms to execute this logic automatically each time the component is destroyed.

Next steps#

πŸŽ‰πŸŽ‰πŸŽ‰ Congratulations! You now know how to manage the memory of the BIM applications you create with IFC.js, so your applications will be 100% free of memory leaks.

πŸ’ͺ Next we are going to look at some advanced model loading tools, such as multithreading and load process event.