SimplePie 1.5 is now available!

SimplePie Documentation.  Learn how to use this thing.  It's way better than going to school.

You are here: Documentation » Frequently Asked Questions » I'm getting memory leaks!

This is an old revision of the document!


I'm getting memory leaks!

When processing a large number of feeds (via a cron job or MySQL loop), a memory leak can occur causing PHP to run out of memory. This is due to PHP Bug #33595 where PHP doesn't release memory when making recursive (i.e. self-referential) object calls.

We've been exploring these issues for quite some time now, but we've not found any definitive workarounds except for:

  • Breaking up the cron jobs and MySQL loops into multiple, smaller chunks so that PHP can release its memory
  • Using set_stupidly_fast() uses less memory, allowing many more feeds to be processed. The downside is that this option also disables data sanitization, which may or may not be an issue for you.

We're watching this bug closely for any information on the best way to work around it, and will implement any fixes we can as we learn about potential solutions to this issue.

Possibly Solution

The problem is due to recursive references within SimplePie (and PHP's poor handling of said references). A solution that works for me is patching vanilla SimplePie 1.0.1 with this:

--- simplepie1/simplepie.inc    (revision 528)
+++ simplepie1/simplepie.inc    (working copy)
@@ -668,6 +668,12 @@
                        $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)
        {

Then all you have to do in your code is ensure that you call $sp->__destruct() 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:

function SimplePie_Loader($url) {
  static $sp = NULL;
  if ($sp !== NULL) { 
    $sp->__destruct(); 
    $sp = NULL; 
  } 
  $sp = new SimplePie($url); 
  return $sp; 
}

I hope this helps someone.

See Also


faq/i_m_getting_memory_leaks.1188211994.txt.gz · Last modified: 2011/03/06 03:56 (external edit)