Three.js:如何正确配置内存中的场景

Posted

技术标签:

【中文标题】Three.js:如何正确配置内存中的场景【英文标题】:Three.js: how to correctly dispose a scene in memory 【发布时间】:2019-08-03 12:27:32 【问题描述】:

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

https://plnkr.co/edit/Z0sXOnXYc2XOV4t9tETv

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

场景 相机 渲染器

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

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

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

现在点击“DISPOSE”按钮,我们将触发以下 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!")

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

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

请有人解释一下发生了什么以及如何正确地在 three.js 中处理东西?

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

【问题讨论】:

看看***.com/a/33199591/1980846 谢谢,试过了,没区别 我也有同样的问题。调用材料和几何形状的处理不会完全清除内存。从场景中移除网格并不能完全清除。并且删除控制台日志并不能完全清除。哈哈。 更多信息请见github.com/mrdoob/three.js/pull/12464 【参考方案1】:

实际上问题是 console.log 语句阻止垃圾收集打印在 chrome 控制台上的对象。删除 console.log 语句解决了这个问题。

【讨论】:

以上是关于Three.js:如何正确配置内存中的场景的主要内容,如果未能解决你的问题,请参考以下文章

Three.js-如何限制3D场景中的摄像机视图?

如何正确加载three.js中的json模型?

如何将fbxloader加载的摄像头添加到three.js中的场景?

如何清除 THREE.JS 场景

如何将图像和纹理添加到 Three.js JSON 对象文件

Blender 导出到 Three.js