[ 
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/%[email protected]%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: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to