Discussion:
[osg-users] How to track down memory leaks?
Igor Spiridonov
2018-07-11 13:07:30 UTC
Permalink
Hi.

I'm facing memory consumption increase If I remove and create new nodes every frame. I don't have it if I use pools but this issue is nagging me anyway. Memory consumption increases gradually and does't stop although visually a scene looks ok and no lags. I have found this interesting post -
OpenSceneGraph memory usage when resetting scene (https://stackoverflow.com/questions/37205327/openscenegraph-memory-usage-when-resetting-scene)

Does this cache really exist? If it does then how to track down memory leaks in such situation?

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=74307#74307
Sam Brkopac
2018-07-11 15:28:09 UTC
Permalink
Not really sure what you mean by memory leaks. If you don't want the cache to cache any objects then disable it. This will have the trade off of having to parse / upload a node every time you remove it and then re-add it.

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=74311#74311
Robert Osfield
2018-07-11 16:20:42 UTC
Permalink
HI Igor,

You don't provide enough information to know what might be causing the
increasing in memory so we can't provide any specific guidance. In
general the OSG's memory management is pretty solid, there are areas
where data is cached either explicitly or implicitly due to
restrictions due to the GL memroy model.

In the osgDB::FileCache but this is only associated with loading and
reusing loaded models and is off by default so unless you have
specifically enabled this and loading adding to the scene graph then
removing from the scene graph.

Then there is the OpenGL side, to rendering with OpenGL you have to
create texture objects, buffer objects and display lists that are all
cached within OpenGL driver memory, when you delete the corresponding
scene graph objects these GL objects can't be deleted right away so
the OSG caches them and then flushes these caches during the next
frame. It does like flush in a lazy way though, and will attempt to
reuse GL objects when you request new GL objects of the same size and
format of the cached GL objects. This reuse of cached and waiting
to be deleted GL objects really helps with performance for dynamic
scene graphs.

While this caching on the GL side can initially grow it's not a leak,
it's just delayed clean up and it should stabilize after a while.

Then there is bugs in your own program, or perhaps even issues with
how you are measuring the "leak". We don't have your program in front
of us, we don't have your data, or any of your tests results so
basically can't really do anything more - you are the only with all
the tools in front of you.

Robert.
Igor Spiridonov
2018-07-12 15:15:12 UTC
Permalink
Hello Robert.

I have found the memory leak cause. Look like I don't understand how osg works.
I have a root node and its child node. I add UpdateCallback to the root node and inside this callback i remove child nod's drawables and add another ones. I check reference count before I remove them and it's 2 for some reason. My remove decreases it on 1 but it's not enough. Looks like viewer or something else keeps these drawables and therefore memleak happens.

I checked reference count of drawables after I add them to child's node and it's always 1 but when drawables come again to UpdateCallback it becomes 2.

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=74323#74323
Robert Osfield
2018-07-12 15:57:45 UTC
Permalink
Hi Igor,
Post by Igor Spiridonov
I have found the memory leak cause. Look like I don't understand how osg works.
I have a root node and its child node. I add UpdateCallback to the root node and inside this callback i remove child nod's drawables and add another ones. I check reference count before I remove them and it's 2 for some reason. My remove decreases it on 1 but it's not enough. Looks like viewer or something else keeps these drawables and therefore memleak happens.
I checked reference count of drawables after I add them to child's node and it's always 1 but when drawables come again to UpdateCallback it becomes 2.
The OSG's rendering backend retains a ref_ptr<> to the StateSet and
Drawables required for the current frame, but nothing beyond this.
It's not a memory leak at though, this is all cleaned up robustly.

If there is an actual leak in your program then perhaps you've created
a circular reference somewhere, could you have a child object, or
callback perhaps that holds a ref_ptr<> to a parent?

Robert.
Igor Spiridonov
2018-07-12 16:21:16 UTC
Permalink
No, why would I have a circular reference? And yes, I'm aware that circular references don't work with smart pointers. I will create a simple example which reproduces this issue.

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=74328#74328
Robert Osfield
2018-07-12 17:29:44 UTC
Permalink
Post by Igor Spiridonov
No, why would I have a circular reference?
The OSG doesn't generally leak unless you do something pretty odd, the
codebase is pretty heavily tested now.

So we can only guess as to what might be wrong. Circular references
is one possibility. It might be something else odd that you are
doing. The small example that reproduces will be really helpful, as
there isn't else we can suggest at this point, so we just have to look
at code that illustrates the issue.

Robert.
Igor Spiridonov
2018-07-12 19:41:31 UTC
Permalink
Here is simple project which reproduces this issue - RefCountTest (https://bitbucket.org/OmegaDoom/osgrefcounttest)

It's a visual studio project with qt and osg. Not sure you are using windows but the main code in scene.cpp. ref count checks inside "Scene::operator()(osg::Node* node, osg::NodeVisitor* nv)"

I expect both checks to return 1 but first one returns 2 as I explained earlier.

I suppose it's the cause of memleak. I use osg 3.2.

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=74334#74334
Wojciech Lewandowski
2018-07-12 22:49:55 UTC
Permalink
Hi, Igor,

I got interested in this problem and checked your code by converting it to
pure osgViewer. Here are my observations:

I believe you do have circular reference. Your class Scene is a callback.
So RootNode points to callback but Scene callback points to RootNode. Hence
circular ref.
However, this does not explain increased ref count of your geometries. But
I believe this issue can be explained by by lazy clearing of render bins.
RenderBins are not
cleared after Draw but before next frame Draw. So after your Update, your
geometry is Culled/Drawn and lands in RenderLeaves of RenderBin. This
RenderBin is used to draw visible geometries but its not cleared after
Draw. Its cleared later, ie on next Cull/Draw traversal when RenderLeaves
container cleared before it gets filled again. So on next Update you will
notice increased ref count because its also added to RenderLeaves
container. But the next Cull/Draw will clear RenderLeaves and your geometry
will be finally released. Here is your modified test applet code ported to
vanilla osgViewer and modified to use observer_ptr instead of ref_ptr for
RootNode. I have put breakpoint in MyGeometry Destructor to see the call
stack and the call where the geometry is actually released and that way I
found the explanation.

Cheers, hth,
Wojtek Lewandowski
Post by Igor Spiridonov
Here is simple project which reproduces this issue - RefCountTest (
https://bitbucket.org/OmegaDoom/osgrefcounttest)
It's a visual studio project with qt and osg. Not sure you are using
windows but the main code in scene.cpp. ref count checks inside
"Scene::operator()(osg::Node* node, osg::NodeVisitor* nv)"
I expect both checks to return 1 but first one returns 2 as I explained earlier.
I suppose it's the cause of memleak. I use osg 3.2.
------------------
http://forum.openscenegraph.org/viewtopic.php?p=74334#74334
_______________________________________________
osg-users mailing list
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Igor Spiridonov
2018-07-13 16:25:18 UTC
Permalink
Thank you Wojtek for your help.

But as I see it's not so simple. In my program some objects in Update function have ref count 2 but some(surprise, surprise) 1. And memory consumption growing steadily and constantly. The interesting objects those that use vbo. If I set all objects to use display lists then no visible memory leaks. I almost lost my hair and broke my head trying to figure out what's wrong with my program.

Looks like objects are disposed at different time and more objects disposed later. It's not pleasant to deal with such thing at all. You are not sure if it's a real memleak or just feature. I have object pools and they solve this issue but they complicate code. I'd like to get rid of them but I'm still not sure.

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=74337#74337

Loading...