<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Professional PHP &#187; memory-usage</title>
	<atom:link href="http://www.procata.com/blog/archives/tag/memory-usage/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.procata.com/blog</link>
	<description>PHP Programming, Web Development, PHP Advocacy and PHP Best Practices.</description>
	<lastBuildDate>Tue, 20 Oct 2009 00:57:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Rephlux and PHP memory usage with a PEAR surpise</title>
		<link>http://www.procata.com/blog/archives/2004/05/27/rephlux-and-php-memory-usage/</link>
		<comments>http://www.procata.com/blog/archives/2004/05/27/rephlux-and-php-memory-usage/#comments</comments>
		<pubDate>Fri, 28 May 2004 02:37:56 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[memory-usage]]></category>
		<category><![CDATA[pear]]></category>

		<guid isPermaLink="false">http://www.procata.com/blog/archives/2004/05/27/rephlux-and-php-memory-usage/</guid>
		<description><![CDATA[Jon Ramsey came up with a continuous integration tool called Rephlux.  Rephlux periodically checks out your code from CVS and runs your unit tests on it.  It produces a RSS feed of test failures and a RSS feed of CVS revisions.  How cool is that?
In the future it should be possible to [...]]]></description>
			<content:encoded><![CDATA[<p>Jon Ramsey came up with a continuous integration tool called <a href="http://rephlux.sourceforge.net/">Rephlux</a>.  Rephlux periodically checks out your code from CVS and runs your unit tests on it.  It produces a <a href="http://wact.sourceforge.net/rephlux/wact.fails.xml">RSS feed of test failures</a> and a <a href="http://wact.sourceforge.net/rephlux/wact.revisions.xml">RSS feed of CVS revisions</a>.  How cool is that?</p>
<p>In the future it should be possible to automatically build releases and documentation when all the tests pass.  Hopefully, this will help improve our record of releasing on the <a href="http://wact.sourceforge.net/">WACT</a> project.  With one formal release in nearly a year of active development, our record is dismal as <a href="http://www.phppatterns.com/index.php/article/articleview/104/1/2/">Harry diplomatically points out</a>.</p>
<p>Jon is running Rephlux remotely for WACT right now because we are having a problem getting our full test suite to run in the 8M limit that sourceforge imposes on PHP.  We have 97 test cases, 541 test functions, and 1927 assertions in our test suite. This will only grow.  The full test suite includes over 350 PHP files when it runs.  </p>
<p>Since there isn&#8217;t much we can do about unincluding files to free up memory, I decided to take a look at the data that gets stored to see if there was any low hanging fruit there.  I wanted to look and see if any of the code we are using keeps any data in global variables that it might be able to release when done to allow the space to be garbage collected.</p>
<p>So, I added a quick and dirty little hack to get an idea of the size of the various global variables that were left over after a test run.<br />
<pre class="php">&nbsp;
    <span style="color: #b1b100;">foreach</span> <span style="color: #66cc66;">&#40;</span><a href="http://www.php.net/array_keys"><span style="color: #000066;">array_keys</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$GLOBALS</span><span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #0000ff;">$key</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
        <a href="http://www.php.net/echo"><span style="color: #000066;">echo</span></a> <span style="color: #ff0000;">&quot;$key=&quot;</span> . <a href="http://www.php.net/strlen"><span style="color: #000066;">strlen</span></a><span style="color: #66cc66;">&#40;</span><a href="http://www.php.net/serialize"><span style="color: #000066;">serialize</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$GLOBALS</span><span style="color: #66cc66;">&#91;</span><span style="color: #0000ff;">$key</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
    <span style="color: #66cc66;">&#125;</span>
&nbsp;</pre><br />
Most of the globals that were left over were tiny, but there was one that stood out.  That was something from PEAR:<br />
<pre class="php">&nbsp;
_PEAR_destructor_object_list=<span style="color: #cc66cc;">146270</span>
&nbsp;</pre><br />
Looking in to this further I found that the PEAR base class registers a rather dubious destructor for every object that inherits from it:<br />
<pre class="php">&nbsp;
    <span style="color: #000000; font-weight: bold;">function</span> _PEAR<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span>-&gt;_debug<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
            <a href="http://www.php.net/printf"><span style="color: #000066;">printf</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;PEAR destructor called, class=%sn&quot;</span>, <a href="http://www.php.net/get_class"><span style="color: #000066;">get_class</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span>
    <span style="color: #66cc66;">&#125;</span>
&nbsp;</pre><br />
To support this gem, PEAR puts a reference to every object instance ever instantiated that inherits from <code>PEAR</code> into the global variable <code>_PEAR_destructor_object_list</code>.   There the object stays until the deconstruction shutdown function is called.  This reference prevents garbage collection of any of objects inheriting from <code>PEAR</code> or the memory they reference during the lifetime of the script.  And it does this for no good reason at all.</p>
<p>I&#8217;ve <a href="http://forums.devnetwork.net/viewtopic.php?p=90455#90455">expressed my opinion of <code>pear.php</code></a> before and this only reinforces it.  </p>
<p>The only PEAR module that WACT requires is <a href="http://pear.php.net/package/XML_HTMLSax"><code>XML_HTMLSax</code></a>, a handy parser for HTML with an XML parsing interface.  I&#8217;ve always been a little bit uncomfortable with its dependency on <code>pear.php</code> and the deployment issues that this introduces into WACT.  WACT also has optional components that reference other PEAR packages, such as PEAR::DB, PEAR::MDB and PEAR::MDB2.  Fortunately a more typical WACT use case only instantiates a handful of PEAR objects.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.procata.com/blog/archives/2004/05/27/rephlux-and-php-memory-usage/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
