javascript - Three.js:如何正确处理内存中的场景

标签 javascript memory-leaks three.js garbage-collection google-chrome-devtools

我在使用 three.js 消除内存泄漏时遇到很多问题在 react 性应用程序中。调查问题,我发现我什至无法正确处理场景(没有渲染)。 让我告诉你:

https://plnkr.co/edit/Z0sXOnXYc2XOV4t9tETv

在上面的示例中,最初实例化了 3 个三个对象(如您所见,没有进行渲染,只是实例化对象):

  • 场景
  • 相机
  • 渲染器

使用 chrome devtools 让我们在加载页面后立即拍摄内存快照:

enter image description here

现在让我们点击“ADD 1000 MESHES”按钮,您可以猜到它只是创建 1000 个网格(BoxGeometry + MeshBasicMaterial)并将它们添加到场景对象。 让我们拍摄另一个内存快照并查看与前一个快照的比较(增量):

enter image description here

如您所见,我们从 25.2 Mb 增加到 36.2 Mb,内存中添加了 +1000 个网格对象。

现在点击“DISPOSE”按钮,我们将触发以下处理函数:

 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!")
}

在这个函数中,我们遍历场景并处理每个几何体和 Material 。然后我们将对场景、相机和渲染器的引用设置为空,最后我们删除监听器以避免内存泄漏。 让我们点击 DISPOSE 按钮并拍摄另一个内存快照。我预计垃圾收集器将从内存中完全删除与 1000 个网格(Mesh、Matrix4、Vector3、BoxGeometry 等)相关的所有数据,但如果我们拍摄另一个内存快照,我们会发现一些非常不同的东西:

enter image description here

似乎删除了 1000 个 Mesh 对象,但内存使用量与之前的快照几乎相同(34.6 vs 36.2 Mb)。 Vector3、Matrix4、Quaternion 和 Euler 对象中有一些丢弃,但大多数对象会保留在内存中,不会从垃圾收集器中收集。事实上,如果我们将快照 3 与快照 1 进行比较,我们会发现:

enter image description here

请有人解释一下这是怎么回事,以及如何在 three.js 中正确处理这些东西?

三.js:102 谷歌浏览器:72.0.3626.121(64 位)

最佳答案

实际上问题出在 console.log 语句上,它阻止垃圾回收打印在 chrome 控制台上的对象。删除 console.log 语句解决了问题。

关于javascript - Three.js:如何正确处理内存中的场景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55131538/

相关文章:

javascript - 带有TextGeometry和旋转问题的AxisHelper上的标签

javascript - Threejs 天空盒超出范围

javascript - 动态数组 promise 序列

Javascript/html 保留 url 参数

ios - 分配对象的潜在泄漏

java - Tomcat 7.0.50 中的内存泄漏

javascript - 使用 JavaScript 更改内联 CSS

javascript - 从 Javascript 中的递归函数返回对象数组

memory-management - 使用 RefCell 和 Rc 处理循环图中的内存泄漏

javascript - 将纹理与 Three.js 和 PLY 文件一起使用