-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WebGLRenderLists: Fix the issue that memory for disposed objects is not released #12464
Conversation
Hi, |
I came across this issue hence renderLists is exposed by the renderer so you can do: renderer.renderLists.dispose(); to drop all the references to objects, materials etc after removing a set of objects or finishing with a camera / scene combination. Not an elegant solution but it works, and allows the reductions in per frame heap allocs introduced by renderLists to be maintained. |
You mean, And I don't think |
Ah, you meant allocating new memory here if we clear OK, I need to update not to allocate new memory each frame... |
This reverts commit 871abf5.
… keep the references of already disposed objects
Updated |
Correct, that's the allocation the render lists caches. Don't know what the performance hit is of clearing all the references, in most cases, with an unchanged number of render items between frames you could probably avoid most of this clearing by using renderListIndex as a high water mark from the previous frame and clear from renderListIndex to renderList.length - 1 : That is, the RenderItems that haven't been overwritten in the previous frame. I think this would in the common case avoid most of the overhead? The renderLists.dispose() function is the only answer in some cases where a camera/scene combination won't be reused, but yes it is a very blunt object and a bit ugly except in special cases ( I required it after a rtt pass. |
Updated. I think having @mrdoob Let me know if you don't wanna have |
We should merge this PR or a similar solution. There are scenarios where Although 90 of the 100 objects are removed, the internal |
This is how the code used to be before. I changed it because, depending on the scene, it would be creating and deleting objects all the time. Would using |
@mrdoob |
Our application suffers from this in production and we are seeing GPU process crashes due to a memory leak. Running
|
in WebGLRenderList.sort() you could do renderItems.length = transparent.length + opaque.length; to limit the cache to the current amount used. Its the separation of cache between (scene, camera ) pairs that gives the bulk of the benefit here I think rather than caching withing a (scene, camera) pair, and would handle this case without setting arbitrary limits. |
What about clear all of the renderItems after each render?
Sorry, never mind. I didn't check all of the commits. This pr will solve the problem. |
@sgaoae I think the PR implemented this approach but in a slightly different way. Clearing the internal |
@sgaoae if you have a case where the object count in a scene reduces significantly as you propose you can always use the brute force approach which removes all the references, if this PR is not adopted. renderer.renderLists.dispose(); |
Just stumbled upon this issue by searching the web for "renderItems memory leak", as my app rebuilds the scene quite often, the suggestion @aardgoose made (#12464 (comment)) seems perfect for me so far. |
I'm using a lot of large BufferGeometries and manually removing all the attributes from them before disposing, frees up most of the memory (r104). for (const key in geometry.attributes) {
geometry.removeAttribute(key);
}
geometry.setIndex([]);
geometry.dispose(); |
Closing in favor of #18411. |
This PR fixes #12447
Let me know if there's any special reasons that
renderItems
wasn't cleared ininit()