You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-dev@xerces.apache.org by "Boris Kolpackov (JIRA)" <xe...@xml.apache.org> on 2009/10/01 09:04:23 UTC

[jira] Commented: (XERCESC-1508) createDocumentType does not release memory when document released/deleted

    [ https://issues.apache.org/jira/browse/XERCESC-1508?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12761113#action_12761113 ] 

Boris Kolpackov commented on XERCESC-1508:
------------------------------------------

I chatted to Alberto about this. Here is the log of our conversation. My understanding is that it is better to use doc->createDocumentType() than impl->createDocumentType(). The same conclusion as Hal Black arrived at in his last comment.

(06:45:40 PM) boseko_1278: Any thoughts on this: https://issues.apache.org/jira/browse/XERCESC-1508
(06:47:12 PM) Alberto: the DOMDocument expects the DTD to come from its pool
(06:47:21 PM) Alberto: so it doesn't delete it
(06:47:46 PM) Alberto: but if the user allocates the DTD from the DOMImplementation object, it simply points to it 
(06:48:14 PM) boseko_1278: So why the memory leak then?
(06:49:50 PM) Alberto: from what I recall, the leak doesn't exist; the owner of the DTD is the DOMImplementation, and will be freed only when shutting down Xerces
(06:54:19 PM) boseko_1278: HM, and if we call release() on DocType, it is still not released?
(06:55:37 PM) Alberto: when you release a node, you are simply putting it in a list for being recycled later
(06:55:43 PM) Alberto: you are not deleting anything
(06:56:05 PM) Alberto: DOMDocument::release deletes all the memory in one shot
(06:56:19 PM) Alberto: but if the DTD didn't come from that memory pool, it is not deleted
(06:56:33 PM) boseko_1278: Yes, I understand
(06:57:16 PM) boseko_1278: It just seems to me that DOMDocument and DOMDocumentType are the same "kind" of objects. They are created by DOMImplementation
(06:57:40 PM) boseko_1278: But DOMDocument you can release with a call to release() while DOMDocumentType you cannot. Strange
(06:58:10 PM) Alberto: the issue is that a DTD can be created both as part of a document, and as a standalone object
(06:58:26 PM) boseko_1278: We are talking about different things.
(06:59:16 PM) boseko_1278: Let me put it this way: If I explicitly call release() on DOMDocumentType object that was created by DOMImplementation, will the memory be freed/reused?
(07:07:59 PM) Alberto: it's middle way
(07:09:12 PM) Alberto: if you call release on a DTD created by DOMImplementation, it will delete itself, but the memory used to store the lists of entities and elements comes from a static DOMDocument
(07:09:25 PM) Alberto: that is deleted at shutdown
(11:01:09 AM) boseko_1278: So you are saying that some parts of DOMDocumentType will be released and some won't
(11:02:34 AM) boseko_1278: Are those lists of entities and elements shared among all DOMDocumentTypes?
(11:10:46 AM) Alberto: the lists are per DTD
(11:10:46 AM) Alberto: but yes, the major part of the memory will not be released
(11:12:41 AM) boseko_1278: so, that's a bug then
(11:13:27 AM) boseko_1278: and there doesn't seem to be any workaround
(11:23:20 AM) Alberto: well, it's more a design issue
(11:23:20 AM) Alberto: who wrote it assumed that the DOMImpletation::createDTD was not an often used API
(11:23:20 AM) Alberto: and that was acceptable to delay the deletion of the memory at shutdown
(11:23:20 AM) Alberto: so, the workaround is to use the createDTD method of the DOMDocument
(11:25:13 AM) boseko_1278: Hm, that's sounds easy. Any idea why people don't do it?
(11:51:25 AM) Alberto: the ones who complain about the problem probably have chosen that approach
(11:51:25 AM) Alberto: but I don't know what they find valuable in using it


> createDocumentType does not release memory when document released/deleted
> -------------------------------------------------------------------------
>
>                 Key: XERCESC-1508
>                 URL: https://issues.apache.org/jira/browse/XERCESC-1508
>             Project: Xerces-C++
>          Issue Type: Bug
>          Components: DOM
>    Affects Versions: 2.6.0, 2.7.0
>         Environment: SUSE Linux 9, Red Hat Advanced Server 3.6, Ubuntu 7.04
>            Reporter: peter suggitt
>            Assignee: Gareth Reakes
>         Attachments: DOMDocumentType_leak.cc, play.cpp
>
>
> 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/%3c87vf5bi9gy.fsf@openinformatics.com%3e
> .. 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.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
To unsubscribe, e-mail: c-dev-unsubscribe@xerces.apache.org
For additional commands, e-mail: c-dev-help@xerces.apache.org