首页 文章

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

提问于
浏览
1

我花了很多时间试图找出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 回答

  • 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 .

相关问题