blob: 40dc4cb5bd58fe33f62104efddd0edab94fd2f9e [file] [log] [blame]
Daniel Veillard1177ca42003-04-26 22:29:54 +00001<?xml version="1.0" encoding="ISO-8859-1"?>
2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /><link rel="SHORTCUT ICON" href="/favicon.ico" /><style type="text/css">
Daniel Veillard373a4752002-02-21 14:46:29 +00004TD {font-family: Verdana,Arial,Helvetica}
5BODY {font-family: Verdana,Arial,Helvetica; margin-top: 2em; margin-left: 0em; margin-right: 0em}
6H1 {font-family: Verdana,Arial,Helvetica}
7H2 {font-family: Verdana,Arial,Helvetica}
8H3 {font-family: Verdana,Arial,Helvetica}
Daniel Veillardb8cfbd12001-10-25 10:53:28 +00009A:link, A:visited, A:active { text-decoration: underline }
Daniel Veillardd463c992006-02-23 22:07:59 +000010</style><title>Memory Management</title></head><body bgcolor="#8b7765" text="#000000" link="#a06060" vlink="#000000"><table border="0" width="100%" cellpadding="5" cellspacing="0" align="center"><tr><td width="120"><a href="http://swpat.ffii.org/"><img src="epatents.png" alt="Action against software patents" /></a></td><td width="180"><a href="http://www.gnome.org/"><img src="gnome2.png" alt="Gnome2 Logo" /></a><a href="http://www.w3.org/Status"><img src="w3c.png" alt="W3C Logo" /></a><a href="http://www.redhat.com/"><img src="redhat.gif" alt="Red Hat Logo" /></a><div align="left"><a href="http://xmlsoft.org/"><img src="Libxml2-Logo-180x168.gif" alt="Made with Libxml2 Logo" /></a></div></td><td><table border="0" width="90%" cellpadding="2" cellspacing="0" align="center" bgcolor="#000000"><tr><td><table width="100%" border="0" cellspacing="1" cellpadding="3" bgcolor="#fffacd"><tr><td align="center"><h1>The XML C parser and toolkit of Gnome</h1><h2>Memory Management</h2></td></tr></table></td></tr></table></td></tr></table><table border="0" cellpadding="4" cellspacing="0" width="100%" align="center"><tr><td bgcolor="#8b7765"><table border="0" cellspacing="0" cellpadding="2" width="100%"><tr><td valign="top" width="200" bgcolor="#8b7765"><table border="0" cellspacing="0" cellpadding="1" width="100%" bgcolor="#000000"><tr><td><table width="100%" border="0" cellspacing="1" cellpadding="3"><tr><td colspan="1" bgcolor="#eecfa1" align="center"><center><b>Developer Menu</b></center></td></tr><tr><td bgcolor="#fffacd"><form action="search.php" enctype="application/x-www-form-urlencoded" method="get"><input name="query" type="text" size="20" value="" /><input name="submit" type="submit" value="Search ..." /></form><ul><li><a href="index.html" style="font-weight:bold">Main Menu</a></li><li><a href="html/index.html" style="font-weight:bold">Reference Manual</a></li><li><a href="examples/index.html" style="font-weight:bold">Code Examples</a></li><li><a href="guidelines.html">XML Guidelines</a></li><li><a href="tutorial/index.html">Tutorial</a></li><li><a href="xmlreader.html">The Reader Interface</a></li><li><a href="ChangeLog.html">ChangeLog</a></li><li><a href="XSLT.html">XSLT</a></li><li><a href="python.html">Python and bindings</a></li><li><a href="architecture.html">libxml2 architecture</a></li><li><a href="tree.html">The tree output</a></li><li><a href="interface.html">The SAX interface</a></li><li><a href="xmlmem.html">Memory Management</a></li><li><a href="xmlio.html">I/O Interfaces</a></li><li><a href="library.html">The parser interfaces</a></li><li><a href="entities.html">Entities or no entities</a></li><li><a href="namespaces.html">Namespaces</a></li><li><a href="upgrade.html">Upgrading 1.x code</a></li><li><a href="threads.html">Thread safety</a></li><li><a href="DOM.html">DOM Principles</a></li><li><a href="example.html">A real example</a></li><li><a href="xml.html">flat page</a>, <a href="site.xsl">stylesheet</a></li></ul></td></tr></table><table width="100%" border="0" cellspacing="1" cellpadding="3"><tr><td colspan="1" bgcolor="#eecfa1" align="center"><center><b>API Indexes</b></center></td></tr><tr><td bgcolor="#fffacd"><ul><li><a href="APIchunk0.html">Alphabetic</a></li><li><a href="APIconstructors.html">Constructors</a></li><li><a href="APIfunctions.html">Functions/Types</a></li><li><a href="APIfiles.html">Modules</a></li><li><a href="APIsymbols.html">Symbols</a></li></ul></td></tr></table><table width="100%" border="0" cellspacing="1" cellpadding="3"><tr><td colspan="1" bgcolor="#eecfa1" align="center"><center><b>Related links</b></center></td></tr><tr><td bgcolor="#fffacd"><ul><li><a href="http://mail.gnome.org/archives/xml/">Mail archive</a></li><li><a href="http://xmlsoft.org/XSLT/">XSLT libxslt</a></li><li><a href="http://phd.cs.unibo.it/gdome2/">DOM gdome2</a></li><li><a href="http://www.aleksey.com/xmlsec/">XML-DSig xmlsec</a></li><li><a href="ftp://xmlsoft.org/">FTP</a></li><li><a href="http://www.zlatkovic.com/projects/libxml/">Windows binaries</a></li><li><a href="http://www.blastwave.org/packages.php/libxml2">Solaris binaries</a></li><li><a href="http://www.explain.com.au/oss/libxml2xslt.html">MacOsX binaries</a></li><li><a href="http://libxmlplusplus.sourceforge.net/">C++ bindings</a></li><li><a href="http://www.zend.com/php5/articles/php5-xmlphp.php#Heading4">PHP bindings</a></li><li><a href="http://sourceforge.net/projects/libxml2-pas/">Pascal bindings</a></li><li><a href="http://libxml.rubyforge.org/">Ruby bindings</a></li><li><a href="http://tclxml.sourceforge.net/">Tcl bindings</a></li><li><a href="http://bugzilla.gnome.org/buglist.cgi?product=libxml2">Bug Tracker</a></li></ul></td></tr></table></td></tr></table></td><td valign="top" bgcolor="#8b7765"><table border="0" cellspacing="0" cellpadding="1" width="100%"><tr><td><table border="0" cellspacing="0" cellpadding="1" width="100%" bgcolor="#000000"><tr><td><table border="0" cellpadding="3" cellspacing="1" width="100%"><tr><td bgcolor="#fffacd"><p>Table of Content:</p><ol><li><a href="#General3">General overview</a></li>
Daniel Veillard8a469172003-06-12 16:05:07 +000011 <li><a href="#setting">Setting libxml2 set of memory routines</a></li>
Daniel Veillard0b28e882002-07-24 23:47:05 +000012 <li><a href="#cleanup">Cleaning up after parsing</a></li>
13 <li><a href="#Debugging">Debugging routines</a></li>
14 <li><a href="#General4">General memory requirements</a></li>
Daniel Veillardfabafd52006-06-08 08:16:33 +000015</ol><h3><a name="General3" id="General3">General overview</a></h3><p>The module <code><a href="http://xmlsoft.org/html/libxml-xmlmemory.html">xmlmemory.h</a></code>providesthe
16interfaces to the libxml2 memory system:</p><ul><li>libxml2 does not use the libc memory allocator directly
17 butxmlFree(),xmlMalloc() and xmlRealloc()</li>
18 <li>those routines can be reallocated to a specific set of
19 routine,bydefault the libc ones i.e. free(), malloc() and realloc()</li>
Daniel Veillard0b28e882002-07-24 23:47:05 +000020 <li>the xmlmemory.c module includes a set of debugging routine</li>
Daniel Veillardfabafd52006-06-08 08:16:33 +000021</ul><h3><a name="setting" id="setting">Setting libxml2 set of memory routines</a></h3><p>It is sometimes useful to not use the default memory allocator,
22eitherfordebugging, analysis or to implement a specific behaviour on
23memorymanagement(like on embedded systems). Two function calls are available
24to doso:</p><ul><li><a href="http://xmlsoft.org/html/libxml-xmlmemory.html">xmlMemGet()</a>whichreturn
25 the current set of functions in use by the parser</li>
26 <li><a href="http://xmlsoft.org/html/libxml-xmlmemory.html">xmlMemSetup()</a>whichallow
27 to set up a new set of memory allocation functions</li>
28</ul><p>Of course a call to xmlMemSetup() should probably be done beforecallingany
29other libxml2 routines (unless you are sure your allocationsroutines
30arecompatibles).</p><h3><a name="cleanup" id="cleanup">Cleaning up after parsing</a></h3><p>Libxml2 is not stateless, there is a few set of memory
31structuresneedingallocation before the parser is fully functional (some
32encodingstructuresfor example). This also mean that once parsing is finished
33there isa tinyamount of memory (a few hundred bytes) which can be recollected
34if youdon'treuse the parser immediately:</p><ul><li><a href="http://xmlsoft.org/html/libxml-parser.html">xmlCleanupParser()</a>isa
35 centralized routine to free the parsing states. Note that
36 itwon'tdeallocate any produced tree if any (use the xmlFreeDoc()
37 andrelatedroutines for this).</li>
38 <li><a href="http://xmlsoft.org/html/libxml-parser.html">xmlInitParser()</a>isthe
39 dual routine allowing to preallocate the parsing statewhich can beuseful
40 for example to avoid initialization reentrancyproblems when usinglibxml2
41 in multithreaded applications</li>
42</ul><p>Generally xmlCleanupParser() is safe, if needed the state will berebuildat
43the next invocation of parser routines, but be careful of theconsequencesin
44multithreaded applications.</p><h3><a name="Debugging" id="Debugging">Debugging routines</a></h3><p>When configured using --with-mem-debug flag (off by default), libxml2usesa
45set of memory allocation debugging routines keeping track of
46allallocatedblocks and the location in the code where the routine was called.
47Acouple ofother debugging routines allow to dump the memory allocated infos
48toa fileor call a specific routine when a given block number is allocated:</p><ul><li><a href="http://xmlsoft.org/html/libxml-xmlmemory.html">xmlMallocLoc()</a><a href="http://xmlsoft.org/html/libxml-xmlmemory.html">xmlReallocLoc()</a>and<a href="http://xmlsoft.org/html/libxml-xmlmemory.html">xmlMemStrdupLoc()</a>arethe
49 memory debugging replacement allocation routines</li>
50 <li><a href="http://xmlsoft.org/html/libxml-xmlmemory.html">xmlMemoryDump()</a>dumpsall
51 the informations about the allocated memory block leftsin
52 the<code>.memdump</code>file</li>
53</ul><p>When developing libxml2 memory debug is enabled, the tests
54programscallxmlMemoryDump () and the "make test" regression tests will check
55foranymemory leak during the full regression test sequence, this helps
56alotensuring that libxml2 does not leak memory and bullet
57proofmemoryallocations use (some libc implementations are known to be far
58toopermissiveresulting in major portability problems!).</p><p>If the .memdump reports a leak, it displays the allocation functionandalso
59tries to give some informations about the content and structure
60oftheallocated blocks left. This is sufficient in most cases to find
61theculprit,but not always. Assuming the allocation problem is reproducible,
62itispossible to find more easily:</p><ol><li>write down the block number xxxx not allocated</li>
63 <li>export the environment variable XML_MEM_BREAKPOINT=xxxx ,
64 theeasiestwhen using GDB is to simply give the command
Daniel Veillarda8a89fe2002-04-12 21:03:34 +000065 <p><code>set environment XML_MEM_BREAKPOINT xxxx</code></p>
Daniel Veillard0b28e882002-07-24 23:47:05 +000066 <p>before running the program.</p>
67 </li>
Daniel Veillardfabafd52006-06-08 08:16:33 +000068 <li>run the program under a debugger and set a
69 breakpointonxmlMallocBreakpoint() a specific function called when this
70 preciseblockis allocated</li>
71 <li>when the breakpoint is reached you can then do a fine analysis
72 oftheallocation an step to see the condition resulting in
73 themissingdeallocation.</li>
74</ol><p>I used to use a commercial tool to debug libxml2 memory problems
75butafternoticing that it was not detecting memory leaks that simple
76mechanismwasused and proved extremely efficient until now. Lately I have also
77used <a href="http://developer.kde.org/~sewardj/">valgrind</a>with quite
78somesuccess,it is tied to the i386 architecture since it works by emulating
79theprocessorand instruction set, it is slow but extremely efficient, i.e.
80itspot memoryusage errors in a very precise way.</p><h3><a name="General4" id="General4">General memory requirements</a></h3><p>How much libxml2 memory require ? It's hard to tell in average itdependsof
81a number of things:</p><ul><li>the parser itself should work in a fixed amount of memory,
82 exceptforinformation maintained about the stacks of names and
83 entitieslocations.The I/O and encoding handlers will probably account for
84 a fewKBytes.This is true for both the XML and HTML parser (though the
85 HTMLparserneed more state).</li>
86 <li>If you are generating the DOM tree then memory requirements
87 willgrownearly linear with the size of the data. In general for
88 abalancedtextual document the internal memory requirement is about 4
89 timesthesize of the UTF8 serialization of this document (example
90 theXML-1.0recommendation is a bit more of 150KBytes and takes 650KBytes
91 ofmainmemory when parsed). Validation will add a amount of memory
92 requiredformaintaining the external Dtd state which should be linear
93 withthecomplexity of the content model defined by the Dtd</li>
94 <li>If you need to work with fixed memory requirements or don't needthefull
95 DOM tree then using the <a href="xmlreader.html">xmlReaderinterface</a>is
96 probably the best way toproceed, it still allows tovalidate or operate on
97 subset of the tree ifneeded.</li>
98 <li>If you don't care about the advanced features of libxml2likevalidation,
99 DOM, XPath or XPointer, don't use entities, need to workwithfixed memory
100 requirements, and try to get the fastest parsingpossiblethen the SAX
101 interface should be used, but it has knownrestrictions.</li>
Daniel Veillard1177ca42003-04-26 22:29:54 +0000102</ul><p></p><p><a href="bugs.html">Daniel Veillard</a></p></td></tr></table></td></tr></table></td></tr></table></td></tr></table></td></tr></table></body></html>