about:benjie

Random learnings and other thoughts from an unashamed geek

SimplePie Memory Leak

| Comments

Quote from SimplePie wiki:

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.

This bug has troubled me for a while with Blog Friends, and caused me to stay with older versions of SimplePie. However, today I think I may have fixed it.

I have put up details of my fix on the SimplePie wiki page linked above, but reproduce them here (without syntax highlighting) for your convenience…

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 the vanilla SimplePie 1.0.1 with this:\ \

<code>\ — 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)\ {\ </code>

\ 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; \ }\ </code>

\ I hope this helps someone.

Comments