wiki:Tutorial/OpenSG2/Memleak

Chapter Overview

  1. First Considerations

<< Previous Chapter: Modelling? Tutorial Overview Next Chapter: Using the fcd2code generator >>

First Considerations

Use professional tools such as Valgrind or anything else that enables you to find memory leaks in your application. If you have no access to such tools, you might find the following useful. See this and this FAQ first.

As you might have already read, OpenSG does use Ptr's and/or RefPtr's instead of ordinary C pointers. Those are powerful constructs that allows us to use refcounting. In order to create any OpenSG object instance you use the respective create method. Each time you do so, OpenSG stores this new instance into a STL vector by just using push_back. So, be aware that this internal vector will always grow, it never shrinks (mainly because of performance considerations). So OpenSG is keeping track of all the allocated (and disallocated!) instances. You do have access to the list and of course you can print it:

First of all, after you have called osgInit(), OpenSG has created some internal static variables, to avoid to show them as user allocated, you should get the offset index right after calling osgInit():

#include <OpenSG/OSGFieldContainerFactory.h>

//...

    osgInit( argc, argv );

    fcStoreSize = FieldContainerFactory::the()->getFieldContainerStore()->size();

void printOSGInstances()
{
        int notNull = 0;
        UInt32 numContainers = FieldContainerFactory::the()->getNumContainers();
        for (UInt32 i=fcStoreSize;i<numContainers;++i)
        {
                FieldContainer* fc = FieldContainerFactory::the()->getContainer(i);
                if (fc != 0)
                {
                        notNull++;
                        AttachmentContainer* ac = dynamic_cast<AttachmentContainer*>(fc);
                        if (ac == 0)
                        {
                                Attachment* a = dynamic_cast<Attachment*>(fc);
                                if (a != 0)
                                {
                                        FieldContainer* dad = 0;
                                        if (a->getParents().size() > 0)
                                        {
                                                dad = a->getParent(0);
                                        }
                                        ac = dynamic_cast<AttachmentContainer*>(dad);
                                }
                        }
                        const Char8* name = getName(ac);
                        if (name != 0)
                        {
                                printf("Detected living FC %s (%s) %p refcount %d\n", fc->getTypeName(), name, fc, fc->getRefCount());
                        }
                        else
                        {
                                printf( "Detected living FC %s %p refcount %d\n", fc->getTypeName(), fc, fc->getRefCount() );
                        }
                }
        }
        printf( "%d out of %d FC's have not been destroyed\n", notNull, numContainers-fcStoreSize );
}


Before you call printOSGInstances(), make sure to call Thread::getCurrent()->getChangeList()->clearAll(); in order to clear the change list. You can print this list anytime in your application, typically you print it right before exiting in debug mode in order to see if there are any allocated FC's remaining in memory. If you have like 4 (or something in this magnitude) FC's remaining, don't worry, OpenSG sometimes allocates some static variables, e.g. when you create a SimpleGeometry, OpenSG allocates a few static variables which will show up in your FC list. Now, If you're a beginner you'll typically have a huge list of non dealloced FC's, don't panic, there are some things you should know, the most common pitfalls are described in the following sections!

The output might look somwhow anonymous, you might have no clue which FC matches the FC you've created in your code. The only thing you know is that the list is sorted in order of creation time (most recently allocated objects appear at the end of the list). However, some FC (more precisely, FC which derive from "AttachmentContainer") can carry a name attachment which can be set with the convenience method "setName". If you set those, you'll see them in you output of printOSGInstances():

#include <OpenSG/OSGNameAttachment.h>

  // ...

  ImagePtr img = Image::create();

  setName( img, "My Whatever Image Name" );

Unfortunately some frequently used OpenSG objects (e.g. ChunkMaterial, BlendChunk, etc) don't derive from AttachmentContainer and thus you can't associate names to them.


<< Previous Chapter: Modelling? Tutorial Overview Next Chapter: Using the fcd2code generator >>
Last modified 7 years ago Last modified on 05/27/10 22:15:38