Properly cleaning meshes when they're no longer necessary

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
nikoomba
Competition winner
Posts: 22
Joined: Wed Mar 09, 2011 11:35 am

Properly cleaning meshes when they're no longer necessary

Post by nikoomba »

Hello,

I'm probably doing something elementary wrong, but I really need some help with this as I've got a huge memory problem in my game.

I've made an example project to demonstrate the problem I'm having:

main.cpp

Code: Select all

 
#include <irrlicht.h>
#include "TestObject.h"
 
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
 
/*#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif*/
 
int main()
{
        IrrlichtDevice* m_Device = createDevice(video::EDT_OPENGL, dimension2d<u32>(640, 480), 16, 0, 0, 0, 0);
        IVideoDriver* m_Driver = m_Device->getVideoDriver();
        ISceneManager* m_Smgr = m_Device->getSceneManager();
        IGUIEnvironment* m_Guienv = m_Device->getGUIEnvironment();
 
        TestObject* m_TestObject = new TestObject();
        m_TestObject->Init(m_Device);
 
        m_TestObject->Terminate();
 
        m_Smgr->addCameraSceneNode(0, vector3df(0, 30, -40), vector3df(0, 5 ,0));
 
        while(m_Device->run())
        {
                m_Driver->beginScene(1, 1, SColor(255, 100, 101, 140));
 
                m_Smgr->drawAll();
                m_Guienv->drawAll();
 
                m_Driver->endScene();
        }
 
        m_Device->drop();
 
        return 0;
}
 
TestObject.h

Code: Select all

 
#include <irrlicht.h>
 
#pragma once
 
class TestObject
{
public:
        TestObject(void);
        ~TestObject(void);
        void Init(irr::IrrlichtDevice* p_Device);
        void Terminate();
 
private:
        irr::scene::IMeshSceneNode* m_Level;
 
        irr::IrrlichtDevice* m_Device;
};
 
TestObject.cpp

Code: Select all

 
#include "TestObject.h"
 
TestObject::TestObject(void)
{
 
}
 
TestObject::~TestObject(void)
{
 
}
 
void TestObject::Init(irr::IrrlichtDevice* p_Device)
{
        m_Device = p_Device;
 
        m_Level = m_Device->getSceneManager()->addMeshSceneNode(m_Device->getSceneManager()->getMesh("Media/Environment/lvl01.3ds"));
        m_Level->setRotation(irr::core::vector3df(90, 0, 0));
        m_Level->setMaterialFlag(irr::video::EMF_LIGHTING, 0);
}
 
void TestObject::Terminate()
{
        m_Level->remove();
 
        delete this;
}
 
Now, I expected that when I delete the m_Level scenenode with the 'remove()' command, it should remove EVERYTHING that has anything to do with the scenenode, including the meshes / textures and such.
This however seems to not be the case, since the memory shows a smaller decrease when using this approach, then when first for example manually dropping the mesh and then using the 'remove()' command.

I'd like to know how to properly clean everything that has to do with the scenenode from memory. I've already tried these:

Code: Select all

 
m_Smgr->clear();
m_Driver->removeAllTextures();
m_Driver->removeAllHardwareBuffers();
m_Guienv->clear();
 
This STILL doesn't seem to remove everything though.
Could someone assist me with solving this problem, please?

Much obliged,
Sjors van Gelderen
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Re: Properly cleaning meshes when they're no longer necessar

Post by serengeor »

Now, I expected that when I delete the m_Level scenenode with the 'remove()' command, it should remove EVERYTHING that has anything to do with the scenenode, including the meshes / textures and such.
This however seems to not be the case, since the memory shows a smaller decrease when using this approach, then when first for example manually dropping the mesh and then using the 'remove()' command.
It doesn't remove meshes or textures. Why? Because they might be used by other nodes. Also if it did it would mean that if you tried to add another node with same texture(s), mesh(es) it would need to reload them from disk, thought probably it would just crash because of missing resources.

If you need to remove mesh(es) remove them using mesh cache, textures - texture cache.

I have looked at the source of scene manager and It seams that it doesn't clear the mesh cache so you should try that too.
Working on game: Marrbles (Currently stopped).
nikoomba
Competition winner
Posts: 22
Joined: Wed Mar 09, 2011 11:35 am

Re: Properly cleaning meshes when they're no longer necessar

Post by nikoomba »

serengeor wrote: It doesn't remove meshes or textures. Why? Because they might be used by other nodes. Also if it did it would mean that if you tried to add another node with same texture(s), mesh(es) it would need to reload them from disk, thought probably it would just crash because of missing resources.

If you need to remove mesh(es) remove them using mesh cache, textures - texture cache.

I have looked at the source of scene manager and It seams that it doesn't clear the mesh cache so you should try that too.
Thanks for your quick reply.

I've tried clearing the mesh cache; and I already cleared the texture cache, but it STILL doesn't seem to remove everything from memory.
Resource Monitor doesn't lie, does it? I think it should be accurate.. Anyways, by the time you reach the end of my game, the RAM usage has increased far too much(from about 200.000(KB) to 700.000(KB) and over), despite the final level being much smaller than the ones before, and I've determined that it's definitely because I can't get rid of everything Irrlicht is loading when I'm making a mesh scenenode.

I've changed the main.cpp file to this:

main.cpp

Code: Select all

 
#include <irrlicht.h>
#include "TestObject.h"
 
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
 
/*#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif*/
 
int main()
{
        IrrlichtDevice* m_Device = createDevice(video::EDT_OPENGL, dimension2d<u32>(640, 480), 16, 0, 0, 0, 0);
        IVideoDriver* m_Driver = m_Device->getVideoDriver();
        ISceneManager* m_Smgr = m_Device->getSceneManager();
        IGUIEnvironment* m_Guienv = m_Device->getGUIEnvironment();
 
        //Breakpoint - Resource Monitor indicates private memory usage of 8.048(KB)
        TestObject* m_TestObject = new TestObject();
        m_TestObject->Init(m_Device);
 
        //Breakpoint - Resource Monitor indicates private memory usage of 29.880(KB)
        m_TestObject->Terminate();
 
        //Breakpoint - Exactly the same amount of private memory usage as at the previous breakpoint
        m_Smgr->getMeshCache()->clear();
        m_Smgr->clear();
 
        m_Driver->removeAllTextures();
        m_Driver->removeAllHardwareBuffers();
 
        //Breakpoint - Resource Monitor indicates private memory usage of 13.992(KB), although a lot less, still not everything is gone because it should be 8.048(KB).
        m_Smgr->addCameraSceneNode(0, vector3df(0, 30, -40), vector3df(0, 5 ,0));
 
        while(m_Device->run())
        {
                m_Driver->beginScene(1, 1, SColor(255, 100, 101, 140));
 
                m_Smgr->drawAll();
                m_Guienv->drawAll();
 
                m_Driver->endScene();
        }
 
        m_Device->drop();
 
        return 0;
}
 
Sorry to bug you guys with this, but it really is important that I fix this issue; I can't even predict what the program will do with these outrageous amounts of memory usage.
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Re: Properly cleaning meshes when they're no longer necessar

Post by serengeor »

I think I also posted something like this, try creating and destroying lets say 25000 of those test objects in a loop and check if the memory usage goes up. I'm pretty sure it won't.
And it's not just meshes and textures that take up memory I think.
Working on game: Marrbles (Currently stopped).
nikoomba
Competition winner
Posts: 22
Joined: Wed Mar 09, 2011 11:35 am

Re: Properly cleaning meshes when they're no longer necessar

Post by nikoomba »

Interesting, the memory doesn't increase indeed..

I'll have to see what else might be wrong in my actual project then.

Thanks for your help, I'll let you know if I find the actual problem with my game.

Have a great day! : )
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Re: Properly cleaning meshes when they're no longer necessar

Post by serengeor »

try using valgrind memory check tool if you're using linux or Visual leak detector if you're under windows and have access to visual studio.
Working on game: Marrbles (Currently stopped).
nikoomba
Competition winner
Posts: 22
Joined: Wed Mar 09, 2011 11:35 am

Re: Properly cleaning meshes when they're no longer necessar

Post by nikoomba »

serengeor wrote:try using valgrind memory check tool if you're using linux or Visual leak detector if you're under windows and have access to visual studio.
Thanks for the recommendations, will do.

The memory problem is now solved, I basically just cleared everything that I could find on the device, scenemanager and the driver.

Thanks a lot everyone, you've been great! :D
Post Reply