2016-05-13 85 views
1

我花了很多时间试图找出OSG的内存管理。 我有一个场景图有几个孩子(实际上是一个基于八叉树的LOD)。OpenSceneGraph在重置场景时的内存使用情况

然而,当我需要重置我的场景(我只是想擦去德场景中的所有节点,也消除了内存),我用

// Clear main osg::Group root node 
m_rootNode->removeChildren(0, m_rootNode->getNumChildren()); 
m_rootNode->dirtyBound(); 

// Clear Main view scene data from osg::Viewer 
m_viewer->setSceneData(nullptr); 

之前,我做这个,我检查我的所有节点使用NodeVisitor模式,发现所有节点的引用计数为1,即从场景中清除它们后,我希望我的内存被释放。但是,这不会发生:我的场景实际上被重置,所有节点都从查看器中消失,但内存仍然被占用。

然而,当我加载另一个场景给我的观众,内存被莫名其妙地改写(即,内存使用量没有增加,因此不存在内存泄漏,但使用的内存始终是相同的)

我不能有这种行为,因为我需要严密控制内存使用情况。我怎样才能做到这一点?

回答

1

看起来像OSG保存数据的缓存实例,无论是CPU端还是GPU端对象。

你可以看看osgDB's options禁用排在首位(CACHE_NONECACHE_ALL & ~CACHE_ARCHIVES)缓存,但是这实际上可以增加你的内存消耗数据可能不会被重新使用和重新加载多次。

您可以指示osg::Texture将CPU端纹理数据上传到OpenGL后释放 - 以防您不再需要它。这可以通过osgUtil::Optimizer::TextureVisitor方便地完成,您可以将其设置为将每个纹理的AutoUnref更改为true。我认为,使用OPTIMIZE_TEXTURE_SETTINGS运行osgUtil :: Optimizer可以达到同样的效果。

然后,收盘下跌场景,当你在你的问题的代码做了之后,你可以明确地指示OSG的数据库寻呼机擦拭它的高速缓存:

for(osgViewer::View v in AllYourViews) 
{ 
    v->getDatabasePager()->cancel(); 
    v->getDatabasePager()->clear(); 
} 

为了最终摆脱所有预先分配的GPU-边对象和它们的CPU端表示,你需要销毁你的视图和GLContext。

+0

谢谢你的提示。你可以给我一些额外的见解:如何实际调用osgDB选项来停用缓存?我如何特别销毁视图和GLContexts? – manatttta