Dear Alberto, thank you for the insight in using the XercesDOMParser correctly.
Mario -----Ursprüngliche Nachricht----- Von: Alberto Massari [mailto:[email protected]] Gesendet: Mittwoch, 8. Juli 2009 14:29 An: [email protected] Betreff: Re: Memory Leak at XercesDOMParser parse function? Hi Mario, if you use getDocument() to get the DOM tree that the parser built, the memory is owned by the parser, and will be deleted when the parser is deleted; if you plan to use a single parser to parse multiple sources and destroy the DOM tree immediately after that, you should call adoptDocument() and the invoke release() on the DOMDocument once you are done with it. Alberto Freimann, Mario wrote: > - Xerces-C++ version number: 2.8 > - Platform: Windows 32Bit > - Operating system and version number: Windows Server 2003 SP 2 > - Compiler and version number: MSVC 6 SP6 > - Built Xerces by myself > > I'm parsing a xml document. Therefore I have a XercesDOMParser instance. I > create this instance once and reuse it to scan one xml document cyclically. > The xml document is valid. I get some data from the document. With every > parse Purify reports a _potential_ memory leak of 1680 Bytes. But If I start > the program without purify the memory consumption increases all the time. So > I think it is a memory leak. Is this a memory leak or do I have to add some > more release or cleanup calls (if so where?)? > > The following code extract eplains the code (error checking deleted for > simplicity). I changed my program to do only the parse function. > > Creating the parser (only once): > ======================= > > DOMDocument* _xmlDoc = NULL; > DOMNode* _actualNode = NULL; > XercesDOMParser* _parser = NULL; > > XMLPlatformUtils::Initialize(); > > _parser = new XercesDOMParser(); > > _parser->setValidationScheme(XercesDOMParser::Val_Auto); > _parser->setIncludeIgnorableWhitespace(false); > _parser->setDoNamespaces(true); > _parser->setDoSchema(false); > > _parser->setErrorHandler(this); > Parsing the file (cyclically): > ==================== > > do > { > if (_xmlDoc!=NULL) > { > _xmlDoc->release(); > } > > try > { > transcodexmlch = XMLString::transcode(filename); > _parser->parse(transcodexmlch); > XMLString::release(&transcodexmlch); > } > catch ()... > > _xmlDoc = _parser->getDocument(); > > _actualNode = _xmlDoc->getDocumentElement(); > } while ( true ); > > > Purify shows a memory leak of total 2680 Bytes. The following trace gives the > biggest memory leak: > > [I] MPK: Potential memory leak of 1288 bytes from 23 blocks allocated in > xercesc_2_8::MemoryManagerImpl::allocate(UINT) [XERCES-C_2_8D.DLL] > Offset 0x00000008 referenced by 0x024e9370, a location in a C++ new > block > Offset 0x00000008 referenced by 0x024ef170, a location in a C++ new > block > Distribution of potentially leaked blocks > Allocation location > new(UINT) [E:\DEVELOP\program\DEBUG\XERCES-C_2_8D.DLL] > xercesc_2_8::MemoryManagerImpl::allocate(UINT) > [E:\develop\xerces-c-src_2_8_0\src\xercesc\internal\MemoryManagerImpl.cpp:35] > { > void* memptr; > try { > => memptr = ::operator new(size); > } > catch(...) { > throw OutOfMemoryException(); > xercesc_2_8::XMemory::new(UINT,MemoryManager::xercesc_2_8 *) > [E:\develop\xerces-c-src_2_8_0\src\xercesc\util\XMemory.cpp:67] > > size_t headerSize = > XMLPlatformUtils::alignPointerForNewBlockAllocation( > > sizeof(MemoryManager*)); > => void* const block = manager->allocate(headerSize + size); > *(MemoryManager**)block = manager; > > return (char*)block + headerSize; > xercesc_2_8::IGXMLScanner::scanStartTagNS(bool&) > [E:\develop\xerces-c-src_2_8_0\src\xercesc\internal\IGXMLScanner.cpp:2393] > if (fGrammarType == Grammar::DTDGrammarType) { > elemDecl = new (fMemoryManager) DTDElementDecl( > qnameRawBuf, uriId, DTDElementDecl::Any, > fMemoryManager > => ); > > elemDecl->setId(fDTDElemNonDeclPool->put((DTDElementDecl*)elemDecl)); > } > else if (fGrammarType == Grammar::SchemaGrammarType) > { > xercesc_2_8::IGXMLScanner::scanContent(void) > [E:\develop\xerces-c-src_2_8_0\src\xercesc\internal\IGXMLScanner.cpp:896] > > case Token_StartTag : > if (fDoNamespaces) > => scanStartTagNS(gotData); > else > scanStartTag(gotData); > break; > xercesc_2_8::IGXMLScanner::scanDocument(InputSource::xercesc_2_8 > const&) > [E:\develop\xerces-c-src_2_8_0\src\xercesc\internal\IGXMLScanner.cpp:214] > else > { > // Scan content, and tell it its not an external > entity > => if (scanContent()) > { > // Do post-parse validation if required > if (fValidate) > xercesc_2_8::XMLScanner::scanDocument(WORD const* const) > [E:\develop\xerces-c-src_2_8_0\src\xercesc\internal\XMLScanner.cpp:460] > } > > Janitor<InputSource> janSrc(srcToUse); > => scanDocument(*srcToUse); > } > > void XMLScanner::scanDocument( const char* const systemId) > xercesc_2_8::AbstractDOMParser::parse(WORD const* const) > [E:\develop\xerces-c-src_2_8_0\src\xercesc\parsers\AbstractDOMParser.cpp:538] > try > { > fParseInProgress = true; > => fScanner->scanDocument(systemId); > } > catch(const OutOfMemoryException&) > { > PAR_XMLDOMParser::parseFile(char *) > [E:\develop\program\source\xmlwrapper.cxx:378] > try > { > transcodexmlch = XMLString::transcode(filename); > => _parser->parse(transcodexmlch); > XMLString::release(&transcodexmlch); > } > catch(const XMLException& toCatch) > > Any help is appreciated. > > > With kind regards, > > Mario Freimann > >
