You are here: Documentation » Frequently Asked Questions » I'm getting memory leaks!
Differences
This shows you the differences between two versions of the page.
faq:i_m_getting_memory_leaks [2008/03/10 17:54] admin Updated instructions for 1.1. |
faq:i_m_getting_memory_leaks [2011/03/06 03:56] (current) |
||
---|---|---|---|
Line 1: | Line 1: | ||
====== I'm getting memory leaks! ====== | ====== I'm getting memory leaks! ====== | ||
- | When processing a large number of feeds, a memory leak can occur causing PHP to run out of memory. This is due to [[http://bugs.php.net/bug.php?id=33595|PHP Bug #33595]] where PHP doesn't release memory when making recursive (i.e. self-referential) object calls. The problem is due to recursive references within SimplePie (and PHP's poor handling of said references). This issue affects all versions of PHP earlier than 5.3 (which has not yet been released). | + | When processing a large number of feeds, a memory leak can occur causing PHP to run out of memory. This is due to [[http://bugs.php.net/bug.php?id=33595|PHP Bug #33595]] where PHP doesn't release memory when making recursive (i.e. self-referential) object calls. The problem is due to recursive references within SimplePie (and PHP's poor handling of said references). This issue affects all versions of PHP earlier than 5.3. |
- | ===== Solution for 1.1 ===== | + | In SimplePie 1.1 and above, you simply need to call the destructor method before unsetting the ''$feed'' and ''$item'' variables: |
- | You simply need to call the destructor method before unsetting the ''$feed'' variable. | + | |
<code php> | <code php> | ||
Line 16: | Line 15: | ||
$feed->__destruct(); // Do what PHP should be doing on it's own. | $feed->__destruct(); // Do what PHP should be doing on it's own. | ||
+ | unset($item); | ||
unset($feed); | unset($feed); | ||
Line 23: | Line 23: | ||
</code> | </code> | ||
- | ===== Possible Solution for 1.0.1 (not officially supported) ===== | + | ===== Other Notes ===== |
- | A solution that works for [[http://www.benjiegillam.com/serendipity/archives/24-SimplePie-Memory-Leak.html|me]] is patching vanilla SimplePie 1.0.1 with this: | + | * SimplePie 1.2 has made many improvements in memory handling, so make sure you're running SimplePie 1.2 or newer to improve memory consumption. |
- | + | * This PHP bug has been fixed in PHP 5.3. Upgrade if you can. | |
- | <code diff> | + | * Retrieving feeds from the cache uses less memory than pulling them down and parsing them in the first place. |
- | --- simplepie1/simplepie.inc (revision 528) | + | * Pull fewer feeds all at once. This can be accomplished with a cron job and careful planning. Pull a smaller set of feeds first so that they can cache. Then pull another set. Then another. Let your pages pull directly from the cache, which uses less memory. |
- | +++ simplepie1/simplepie.inc (working copy) | + | * If you have control over your php.ini file, allocate more system memory to PHP. This will give you more buffer. |
- | @@ -668,6 +668,12 @@ | + | * Many shared hosting plans have limited memory available to PHP per user anyway. You can't expect to parse 1000 feeds with 8 MB of RAM allocated. Take this into account. Perhaps a VPS would be better, or perhaps a cloud computing service like [[http://aws.amazon.com/ec2/|Amazon EC2]] or [[http://www.rackspacecloud.com/cloud_hosting_products/servers|Rackspace Cloud Servers]]. |
- | $this->init(); | + | |
- | } | + | |
- | } | + | |
- | + function __destruct() { | + | |
- | + if (isset($this->data['items']) && is_array($this->data['items'])) foreach (array_keys($this->data['items']) as $k) { | + | |
- | + $this->data['items'][$k]->__destruct(); | + | |
- | + unset($this->data['items'][$k]); | + | |
- | + } | + | |
- | + } | + | |
- | + | ||
- | /** | + | |
- | * Used for converting object to a string | + | |
- | @@ -1521,6 +1527,7 @@ | + | |
- | return false; | + | |
- | } | + | |
- | } | + | |
- | + $locate->__destruct(); | + | |
- | $locate = null; | + | |
- | + | ||
- | $headers = $file->headers; | + | |
- | @@ -2703,6 +2710,9 @@ | + | |
- | $this->feed = $feed; | + | |
- | $this->data = $data; | + | |
- | } | + | |
- | + function __destruct() { | + | |
- | + unset($this->feed); | + | |
- | + } | + | |
- | + | ||
- | function __toString() | + | |
- | { | + | |
- | @@ -10013,6 +10023,9 @@ | + | |
- | $this->timeout = $timeout; | + | |
- | $this->max_checked_feeds = $max_checked_feeds; | + | |
- | } | + | |
- | + function __destruct() { | + | |
- | + unset($this->file); | + | |
- | + } | + | |
- | + | ||
- | function find($type = SIMPLEPIE_LOCATOR_ALL) | + | |
- | { | + | |
- | </code> | + | |
- | + | ||
- | Then all you have to do in your code is ensure that you call ''<nowiki>$sp->__destruct()</nowiki>'' once you are done with the SimplePie instance. | + | |
- | + | ||
- | If you don't need multiple concurrent SimplePie classes (i.e. you use SimplePie in a serial fashion) you could use a custom loader to do that... for example: | + | |
- | + | ||
- | <code php> | + | |
- | function SimplePie_Loader($url) { | + | |
- | static $sp = NULL; | + | |
- | if ($sp !== NULL) { | + | |
- | $sp->__destruct(); | + | |
- | $sp = NULL; | + | |
- | } | + | |
- | $sp = new SimplePie($url); | + | |
- | return $sp; | + | |
- | } | + | |
- | </code> | + | |
===== See Also ===== | ===== See Also ===== | ||
* http://bugs.php.net/bug.php?id=33595 | * http://bugs.php.net/bug.php?id=33595 | ||
* http://groups.drupal.org/node/5066#comment-14927 | * http://groups.drupal.org/node/5066#comment-14927 |
faq/i_m_getting_memory_leaks.txt · Last modified: 2011/03/06 03:56 (external edit)