Page 1 of 2 12 LastLast
Results 1 to 10 of 17

Thread: Memory Leaks (Again?)

  1. #1

    Memory Leaks (Again?)

    I'm using collada-dom (tried both head code and version 1.3.0) via the OpenSceneGraph plugin. So far its done a decent job of importing documents, however I'm finding a bunch of memory leak messages when a visual studio debug session ends. After debugging for a while, the unfreed allocations seem to be the ones done in collada-dom. Am I doing something wrong, or is it just a fact that the library leaks right now. I know this was discussed previously (2006). I'm wondering if the leaks have crept back in.

    My code does call the following cleanup at the end:

    Code :
        ~ReaderWriterDAE()
        {
            if(_dae != NULL){
    			_dae->clear();
                delete _dae;
                DAE::cleanup();
                _dae = NULL;
            }
        }
    Is this not enough to clean things up?

  2. #2
    Senior Member
    Join Date
    Jan 2006
    Location
    Foster City, CA
    Posts
    540
    I tried loading and releasing a document, but didn't see any memory leaks in the debug output. I also tried running COLLADA RT under a debugger, but still didn't see any memory leaks. What version of Visual Studio are you using? I was testing with 2005. Do you have a small test app with full source I can use to reproduce the problem?

    Also, as long as you're using DOM version 1.2.0 or later (1.2.0 was released in Nov 2006), it's not necessary to call DAE::clear or DAE::cleanup. Just deleting the DAE object is enough.

  3. #3
    Thanks for the reply. I'm using Visual Studio 2005 Pro. I don't have a small test app, because I'm using Collada-DOM via the DAE importer in the OpenSceneGraph library, so the code is dependent on that framework. When I saw the messages about memory leaks when I exited the app, I did the following:

    1) Put a breakpoint in the destructor code thats supposed to clean-up the DAE, and made sure it is being called.

    2) Since the leaking allocation numbers were consistent across runs, I used the debug runtimes to break on those allocations, and they all seemed to be coming from in the collada-dom code.

    It could be that I'm using the API incorrectly. Is there any obvious/common pitfalls that could cause this type of memory leaking? I will just go over my code (and the other 3rd party library code) to make sure nothing silly is being done.

  4. #4
    Senior Member
    Join Date
    Jan 2006
    Location
    Foster City, CA
    Posts
    540
    The only thing I can think of is if you use a custom plugin of some sort (custom I/O plugin or error handler), you need to delete the object yourself. The DOM doesn't take ownership of it (I plan to change that at some point).

    Other than that, the DOM does a lot of memory management via reference counting, so you're not responsible for deleting individual elements. I tested the DOM in a few apps and didn't get any memory leak messages in Visual Studio 2005. Let me know if you figure anything out. As you hinted at, the DOM used to leak memory like crazy, but I believe all of those issues have been fixed.

  5. #5
    I PM'd you the details as I was investigating. It seems like it's the _CMData members of a number of classes (seperately defined in domNode, domGeometry, ...) that are at the heart of the leaks. _CMData is defined to be an array of pointers to arrays. The destructors for the various classes (domNode, domGeometry, ...) do not do any specialized cleanup of the arrays. So it would seem like the array of pointers is cleaned up nicely, but the arrays being pointed to have been leaked.

    I made the following change to one class (domNode) and it reduced the number of leaks reported by visual studio. I did it to another class (domGeometry), and it reduced the number of leaks again. It would seem either something is systematically wrong with the classes, or the way they're being used.

    Code :
    	virtual ~domNode() {
    		for( unsigned int i = 0; i < _CMData.getCount(); i++ ) {
    			daeCharArray *CurrentItem = _CMData.get(i);
    			if(CurrentItem)
    			{
    				delete CurrentItem;
    				CurrentItem = NULL;
    				_CMData.set(i,NULL);
    			}
    		}
    	}

    Is this a leak, or am I mistaken?

  6. #6
    Senior Member
    Join Date
    Jan 2006
    Location
    Foster City, CA
    Posts
    540
    Memory ownership in the DOM can be very confusing. This is a good example.

    In this particular situation, it looks like domNode (or any dom* object) calls daeMetaElement::addCMDataArray, which in turn exposes the array via daeMetaElement::getMetaCMData. The daeElement destructor calls that function to get the array, and then frees up the data:
    Code :
    // From daeElement::~daeElement
    if ( _meta != NULL && _meta->getMetaCMData() != NULL )
    {
    	daeTArray< daeCharArray *> *CMData = (daeTArray< daeCharArray *>*)_meta->getMetaCMData()->getWritableMemory(this);
    	for ( unsigned int i = 0; i < CMData->getCount(); i++ )
    	{
    		delete CMData->get(i);
    	}
    }
    If that data isn't being freed it's probably because the elements aren't being destroyed. As I mentioned, they're reference counted, so it's not immediately obvious to me why they wouldn't be destroyed. Circular references maybe?

  7. #7
    Ok. I got it to break in that daeElement destructor for one of my leaking objects. The daeElement seems like its being destroyed correctly. The problem is that when it goes to delete the array elements in that destructor, the array seems empty (zero count)... this is despite the fact that stuff was added to it earlier. I did some more debugging, and it seems like this is a problem with the order in which destructors are called.

    Taking a domMesh object as an example. I can see that the _CMData member (which is declared in the domMesh class) is being destructed/cleaned up as part of the ~domMesh automatic destructor. After that, the domElement destructor is called, but by this time, _CMData is empty and the leak has already occurred. The callstack at the time the _CMData array is emptied looks like this:

    Code :
     	osgdb_daed.dll!daeArray::clear()  Line 36	C++
     	osgdb_daed.dll!daeTArray<daeTArray<char> *>::clear()  Line 155	C++
     	osgdb_daed.dll!daeTArray<daeTArray<char> *>::~daeTArray<daeTArray<char> *>()  Line 145	C++
    >	osgdb_daed.dll!domMesh::~domMesh()  Line 212 + 0x60 bytes	C++
     	osgdb_daed.dll!domMesh::`scalar deleting destructor'()  + 0x2b bytes	C++
     	osgdb_daed.dll!daeElement::release()  Line 30 + 0x35 bytes	C++

    So, to recap, the destructors are called in this order:

    1. ~domMesh
    2. ~domElement

    The _CMData member is automatically destructed in ~domMesh, so by the time ~domElement comes around, it finds an empty array, and fails to properly release the array contents.

  8. #8
    Senior Member
    Join Date
    Jan 2006
    Location
    Foster City, CA
    Posts
    540
    Good catch! I'm in the middle of some other stuff now, but I'll try to look at this tomorrow. Thanks for narrowing it down.

  9. #9
    Great. I'm curious why this wasn't showing up as a leak for you guys, but I'll just be satisfied to see it fixed. Please let me know when you get a chance to fix it.

  10. #10
    Senior Member
    Join Date
    Jan 2006
    Location
    Foster City, CA
    Posts
    540
    I'm not sure why I didn't see the leaks with VS2005. I should've been using valgrind on Linux anyway. Valgrind spotted the _CMData leak as well as a much larger leak that recently slipped into the libxml code. I fixed both leaks in revision 166. Valgrind now reports no leaks in my DOM test app. Thanks again for the help in tracking this down

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •