[
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]