Использование памяти OpenSceneGraph при сбросе сцены

Я потратил много времени, пытаясь разобраться с управлением памятью в OSG. У меня есть граф сцены с несколькими дочерними элементами (на самом деле LOD на основе октодерева).

Однако, когда мне нужно сбросить мою сцену (я просто хочу стереть ВСЕ узлы из сцены, а также стереть память), я использую

// 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, т.е. после очистки их со сцены я ожидаю, что моя память освободится. Однако этого не происходит: моя сцена фактически сбрасывается, все узлы исчезают из просмотра, но память остается занятой.

Тем не менее, когда я загружаю другую сцену в свой просмотрщик, память каким-то образом перезаписывается (т. Е. Использование памяти не увеличивается, поэтому утечки памяти нет, но используемая память всегда одна и та же)

У меня не может быть такого поведения, так как мне нужно тщательно контролировать использование памяти. Как я могу это сделать?


person manatttta    schedule 13.05.2016    source источник


Ответы (1)


Похоже, OSG хранит кэшированные экземпляры ваших данных либо в виде объектов на стороне процессора, либо на стороне графического процессора.

Вы можете просмотреть параметры osgDB, чтобы отключить кэширование в первую очередь (CACHE_NONE, CACHE_ALL & ~CACHE_ARCHIVES), но на самом деле это может увеличить потребление памяти, поскольку данные могут не использоваться повторно и повторно загружаться несколько раз.

Вы можете поручить osg::Texture освободить данные текстуры на стороне ЦП после их загрузки в OpenGL - на случай, если они вам больше не нужны. Это удобно сделать с помощью osgUtil::Optimizer::TextureVisitor, который вы хотите изменить AutoUnref для каждой текстуры на true. Я думаю, что запуск osgUtil::Optimizer с OPTIMIZE_TEXTURE_SETTINGS дает тот же эффект.

Затем, после закрытия вашей сцены, как вы сделали в коде своего вопроса, вы можете явно указать пейджеру базы данных OSG стереть свои кеши:

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

Чтобы окончательно избавиться от всех предварительно выделенных объектов на стороне графического процессора и их представлений на стороне процессора, вам потребуется уничтожить ваши представления и GLContext.

person Kento Asashima    schedule 16.08.2016
comment
Спасибо за ваши подсказки. Не могли бы вы дать мне дополнительную информацию о следующем: как на самом деле вызвать параметры osgDB для деактивации кеша? Как конкретно уничтожить представления и GLContexts? - person manatttta; 23.08.2016