Memory Not Fully Released After Removing Large Model From Scene Graph #1551
-
I loaded a large .obj model(approximately 3800 MB memory usage when loaded) using vsgviewer. Then I used a custom operation opDeferredDeleteNode to safely remove the model from the scene graph:
The node was successfully removed from the scene graph. However, memory usage only drops to around 2300 MB—a reduction of ~1500 MB—but not back to the original baseline. As a further test, I modified the default vsg::Allocator and forced direct calls to malloc/free:
This improved the situation slightly—memory dropped to ~2000 MB—but still not fully released. Is this residual memory usage expected in vsg? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
Your opDeferredDeleteNode class makes me wonder if you don't know about the vsg::DeleteQueue that can be used for scheduling clean up of scene graph objects to avoid delete objects on the CPU that are being rendering on the GPU. The vsg::DatabasePager uses the DeleteQueue to safely delete expired PagedLOD subgraphs, but you can create and your operation that relies upon it's own DeleteQueue if you so wish. I may in the future assign a DeleteQueue to the Viewer to make this all a bit easier for users that have dynamic scene graphs. As for the memory usage, there is CPU memory managed by vsg::Allocator, then there is memory managed as Vulkan objects and memory allocations. You can write your own vsg::Allocator but the default one uses block allocation with affinity so that objects of the same classification get allocated from the blocks with just that type of classification, this approach makes a significant difference to access performance as the scene graph tends to be accessed in phases where particular classes of objects get accessed in quick succession, such as during scene graph traversal. A consequence of block allocation is when you delete individual objects, the part of the block they were allocated from will be marked as free by the block, but the block won't be deallocated, even when all the memory used within it is freed. The VSG will attempt to allocate new objects from existing blocks so being lazy about deleting blocks helps avoid thrashing of allocation and reallocation of memory blocks. You can explicitly clean up empty blocks if you wish by calling: vsg::Allocator::instance()->deleteEmptyMemoryBlocks(); In your app there is no way for me to know what is going on, it could be that there is a bug somewhere, such as orphaned object, or a circular reference that is prevent deletion, or it might simply be everything is working correctly but just not what you were expecting. The vsg::Allocator has a report(std::ostream&) method that you could try to see if that shines more light on what might be going on. You could even just write your own vsg::Allocator to help do your own diagnoistics. Have a look at the vsgallocator example. |
Beta Was this translation helpful? Give feedback.
-
Just to clarify, I think it was me who first posted the deferred delete
operation. That was before vsg:DeleteQueue existed. I haven't investigated
converting to vsg::DeleteQueue yet, but it is probably a better way to go
if native to VSG and designed with a better understanding of how the VSG
allocator works.
Roland Hill
Director
Four Winds Technology Pty Ltd
Spatial Integration <https://www.spatialintegration.com/>
…On Fri, 1 Aug 2025 at 03:18, Robert Osfield ***@***.***> wrote:
Your opDeferredDeleteNode class makes me wonder if you don't know about
the vsg::DeleteQueue that can be used for scheduling clean up of scene
graph objects to avoid delete objects on the CPU that are being rendering
on the GPU.
The vsg::DatabasePager uses the DeleteQueue to safely delete expired
PagedLOD subgraphs, but you can create and your operation that relies upon
it's own DeleteQueue if you so wish. I may in the future assign a
DeleteQueue to the Viewer to make this all a bit easier for users that have
dynamic scene graphs.
As for the memory usage, there is CPU memory managed by vsg::Allocator,
then there is memory managed as Vulkan objects and memory allocations. You
can write your own vsg::Allocator but the default one uses block allocation
with affinity so that objects of the same classification get allocated from
the blocks with just that type of classification, this approach makes a
significant difference to access performance as the scene graph tends to be
accessed in phases where particular classes of objects get accessed in
quick succession, such as during scene graph traversal.
A consequence of block allocation is when you delete individual objects,
the part of the block they were allocated from will be marked as free by
the block, but the block won't be deallocated, even when all the memory
used within it is freed. The VSG will attempt to allocate new objects from
existing blocks so being lazy about deleting blocks helps avoid thrashing
of allocation and reallocation of memory blocks.
You can explicitly clean up empty blocks if you wish by calling:
vsg::Allocator::instance()->deleteEmptyMemoryBlocks();
In your app there is no way for me to know what is going on, it could be
that there is a bug somewhere, such as orphaned object, or a circular
reference that is prevent deletion, or it might simply be everything is
working correctly but just not what you were expecting.
The vsg::Allocator has a report(std::ostream&) method that you could try
to see if that shines more light on what might be going on.
You could even just write your own vsg::Allocator to help do your own
diagnoistics. Have a look at the vsgallocator example.
—
Reply to this email directly, view it on GitHub
<#1551 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAPOEQ4I2ZYVAVXZN5DB23D3LJFWLAVCNFSM6AAAAACC2HHR66VHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTGOJVGAZDMOI>
.
You are receiving this because you are subscribed to this thread.Message
ID: <vsg-dev/VulkanSceneGraph/repo-discussions/1551/comments/13950269@
github.com>
|
Beta Was this translation helpful? Give feedback.
Your opDeferredDeleteNode class makes me wonder if you don't know about the vsg::DeleteQueue that can be used for scheduling clean up of scene graph objects to avoid delete objects on the CPU that are being rendering on the GPU.
The vsg::DatabasePager uses the DeleteQueue to safely delete expired PagedLOD subgraphs, but you can create and your operation that relies upon it's own DeleteQueue if you so wish. I may in the future assign a DeleteQueue to the Viewer to make this all a bit easier for users that have dynamic scene graphs.
As for the memory usage, there is CPU memory managed by vsg::Allocator, then there is memory managed as Vulkan objects and memory allocations. You can write you…