在响应式应用程序中使用three.js来消除内存泄漏时,我遇到了很多问题。在研究问题时,我发现我什至无法正确放置场景(不渲染)。 让我告诉你:
https://plnkr.co/edit/Z0sXOnXYc2XOV4t9tETv
在上面的示例中,最初实例化了3个3个对象(如您所见,仅实例化对象并没有进行渲染):
使用chrome devtools,让我们在加载页面后拍摄内存快照:
现在,我们单击“添加1000个网格”按钮,您可以猜测只需创建1000个网格(BoxGeometry + MeshBasicMaterial)并将其添加到场景对象中即可。 让我们获取另一个内存快照,并查看与上一个快照的比较(增量):
如您所见,我们从25.2 Mb传递到36.2 Mb,并且内存中添加了+1000个Mesh对象。
现在点击“ 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中吗?
Three.js:102 谷歌浏览器:72.0.3626.121(64位)
答案 0 :(得分:-1)
实际上,问题出在console.log语句上,该语句可防止垃圾回收chrome控制台上打印的对象。删除console.log语句即可解决问题。