重置场景时的OpenSceneGraph内存使用情况

时间:2016-05-13 08:44:55

标签: c++ memory memory-management openscenegraph

我花了很多时间试图弄清楚OSG的内存管理。 我有一个有几个孩子的场景图(实际上是一个基于八叉树的LOD)。

然而,当我需要重置我的场景时(我只想从de场景中擦除所有节点并擦除内存),我使用

// 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 个答案:

答案 0 :(得分:1)

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

您可以查看osgDB's options以首先禁用缓存(CACHE_NONECACHE_ALL & ~CACHE_ARCHIVES),但这实际上会增加您的内存消耗,因为数据可能无法重复使用并多次重新加载。

您可以指示osg::Texture在上传到OpenGL后释放CPU端纹理数据 - 以防您不再需要它。这可以通过您想要设置的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。