createDocumentType does not release memory when document released/deleted
-------------------------------------------------------------------------

         Key: XERCESC-1508
         URL: http://issues.apache.org/jira/browse/XERCESC-1508
     Project: Xerces-C++
        Type: Bug
    Versions: 2.6.0    
 Environment: SUSE Linux 9
    Reporter: peter suggitt


Hi

I am writing an aplication that has to create XML documents on the fly for 
interprocess communications.

The problem that I have is that the memory is not being released when I use the 
DOMDocument (documentType) constructor.  I have played around with various 
different ways of releasing the memory including using the 
DOMDocumentType->release() method but alas no luck.  I appreciate that this may 
not seem like a huge issue but as I am looking memory everytime I create a new 
document I feel that this is an issue to be resolved.

I have also found a few excepts on the web talking about this issue and there 
also seems to be a few people who believe this issue to be a case of bad API 
use:
http://mail-archives.apache.org/mod_mbox/xerces-c-dev/200505.mbox/[EMAIL 
PROTECTED]
.. this is followed up by a gentleman named Gareth Reakes from 
PathenonComputing describing that this is to do with the way that the release 
methods have not been called .. I do not believe him:
"Nope, not a real leak. When you free the document the memory pools that were 
used to new things from are deleted so it cleans up all the things like the 
attribute list from the creation of an element."

The below example shows how this is not the case.

I have created the following example code thaqt fully replicates the issue 
including taking stats of the memory usage (RSS) after each document creation 
and deletion.  Please note that in main() I have a commented out version of the 
call to create the document as this shows how the standard constructor for the 
domdocument creates without any memory leaks

///////////////////////////////////////////
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp> // to get the xmlstring
#include <xercesc/dom/DOM.hpp>

#include <iostream>
#include <fcntl.h>
#include <unistd.h>

/////////////////////////////////////////////////////////////////////
// pre decl
XERCES_CPP_NAMESPACE::DOMDocument *createNewDoc();
XERCES_CPP_NAMESPACE::DOMDocument *createNewDocWithType();
int getMemorySize();

/////////////////////////////////////////////////////////////////////
int main()
{
    std::cout << "**************** starting" << std::endl;
    XERCES_CPP_NAMESPACE::XMLPlatformUtils::Initialize();

    for( int i = 0; i < 1000; ++i )
    {
        //XERCES_CPP_NAMESPACE::DOMDocument * doc = createNewDoc();
        XERCES_CPP_NAMESPACE::DOMDocument * doc = createNewDocWithType();
        std::cout << "    - Doing something with the document" << std::endl;
        delete doc;
        usleep(100000);
        std::cout << "* Memory (rss): " << getMemorySize() << std::endl;
    }
    
    XERCES_CPP_NAMESPACE::XMLPlatformUtils::Terminate();
    std::cout << "**************** ending" << std::endl;
    return 0;
}

/////////////////////////////////////////////////////////////////////
XERCES_CPP_NAMESPACE::DOMDocument *createNewDocWithType()
{
    // set up strings
    XMLCh *tName = XERCES_CPP_NAMESPACE::XMLString::transcode( "typeName" );
    XMLCh *pub = XERCES_CPP_NAMESPACE::XMLString::transcode( "pubId" );
    XMLCh *sys = XERCES_CPP_NAMESPACE::XMLString::transcode( "sysId" );
    XMLCh *name = XERCES_CPP_NAMESPACE::XMLString::transcode( "rootName" );

    XERCES_CPP_NAMESPACE::DOMImplementation *imp = 
XERCES_CPP_NAMESPACE::DOMImplementation::getImplementation();
    // create the document type and the doc
    XERCES_CPP_NAMESPACE::DOMDocumentType *type = imp->createDocumentType( 
tName, pub, sys );
    XERCES_CPP_NAMESPACE::DOMDocument *tmp = imp->createDocument( NULL, name, 
type );

    std::cout << "    - created a doc" << std::endl;
    // clean up
    XERCES_CPP_NAMESPACE::XMLString::release(&tName);
    XERCES_CPP_NAMESPACE::XMLString::release(&name);
    XERCES_CPP_NAMESPACE::XMLString::release(&pub);
    XERCES_CPP_NAMESPACE::XMLString::release(&sys);
    std::cout << "    - returning doc" << std::endl;
    return tmp;;
}

/////////////////////////////////////////////////////////////////////
XERCES_CPP_NAMESPACE::DOMDocument *createNewDoc()
{
    // set up strings

    XERCES_CPP_NAMESPACE::DOMImplementation *imp = 
XERCES_CPP_NAMESPACE::DOMImplementation::getImplementation();
    // create the document type and the doc
    XERCES_CPP_NAMESPACE::DOMDocument *tmp = imp->createDocument();

    std::cout << "    - returning doc" << std::endl;
    return tmp;;
}

/////////////////////////////////////////////////////////////////////
int getMemorySize()
{
    char fileName[64];
    int fd;

    snprintf( fileName, sizeof(fileName), "/proc/%d/statm", (int)getpid() );
    fd = open(fileName, O_RDONLY);
    if( fd == -1 )
    {
        return -1;
    }

    char memInfo[128];
    int rval = read( fd, memInfo, sizeof(memInfo)-1 );
    close(fd);
    if( rval <= 0 )
    {
        return -1;
    }
    memInfo[rval] = '\0';
    int rss;
    rval = sscanf( memInfo, "%*d %d", &rss );
    if( rval != 1 )
    {
        return -1;
    }
    return rss * getpagesize() / 1024;

}

/////////////////////////////////////////////////////////////////////

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to