Closed DaFluffyPotato closed 1 month ago
I looked a bit more. It looks like it's the CompositionLayerProjectionView
s briefly stored in ContextObject.render_layers
that don't get deallocated. The other xr.typedef items appear to be children of CompositionLayerProjectionView
.
Here's some useful ref tracing from pympler on CompositionLayerProjectionView:
<class 'xr.typedefs.CompositionLayerProjectionView'>(1987851081552)-+-<class 'xr.typedefs.SwapchainSubImage'>(1987851082576)--<class 'xr.typedefs.Rect2Di'>(1987851081168)--<class 'xr.typedefs.Offset2Di'>(1987851082960)--<class 'dict'>(1987825452224)({'_wrapper': xr.Offset2Di(x=0, y=0)})
+-<class 'xr.typedefs.SwapchainSubImage'>(1987851083344)--<class 'xr.typedefs.Rect2Di'>(1987851083472)--<class 'xr.typedefs.Extent2Di'>(1987851083600)--<class 'dict'>(1987825452544)({'_wrapper': xr.Extent2Di(width=2064, height=2272)})
I had the dictionary print out its contents. I'm guessing it's related to this line in typedefs.py
in the Extent2Di
case.
Comparing id()
s of the SwapchainSubImage
s indicates that the children of CompositionLayerProjectionView
are separate from the SwapchainSubImage
s that references CompositionLayerProjectionView
.
Thank you for investigating this. It does look like those .as_numpy() methods might be creating a circular reference that inhibits garbage collection. I don't remember at the moment if I created those methods just to allow python sequence-like access e.g. 'foo[key] = bar' for sequency openxr data types, or if there was some other reason to allow persistent access to the result of as_numpy()
.
The pympler output was exploding exponentially as I increased depth before, but I got hold of a Extent2Di
reference (one of the parent referers of CompositionLayerProjectionView
) to perform another reference check on and got the following:
<class 'xr.typedefs.Extent2Di'>(1535035926096)-+-<class 'dict'>(1535013239104)({'_wrapper': xr.Extent2Di(width=2064, height=2272)})--<class 'xr.typedefs.c_long_Array_2'>(1535035926224)--<class 'managedbuffer'>(1535035926336)--<class 'memoryview'>(1535035883136)
Between this and the other reference check, that includes all the types that were found as a part of the memory leak before. Increasing the pympler depth from 4 to 5 on the Extent2Di
reference segfaults. Directly checking the referers of memoryview
with pympler's node trees yields no referers.
The deletions I made in the PR fixed the issue for me. I've never had to do lifetime hacks for anything before, so my fix could be very wrong. lol
Closing this since #117 was merged.
Testing the pink_world.py example results in a memory leak (RAM not VRAM).
I added pympler to verify the source of the leak:
Which eventually stabilizes after initialization and continuously yields the following diff:
I've watched the program go from ~100MB to several hundred MB of usage before killing it.
Commenting out the following lines from pink_world.py completely removes the leak:
It seems that the contents of
ContextObject.render_layers
are not getting deallocated even thoughContextObject.frame_loop()
does aself.render_layers = []
prior to yielding each frame.I believe all the examples including
hello_xr.py
have leaks.I might look more into the issue later if I have the time.