问题
I'm using SimplePie with PHP 5.3 (with gc enabled) to parse my RSS feeds. This works well and without problems when doing something like the following:
$simplePie = new SimplePie();
$simplePie->set_feed_url($rssURL);
$simplePie->enable_cache(false);
$simplePie->set_max_checked_feeds(10);
$simplePie->set_item_limit(0);
$simplePie->init();
$simplePie->handle_content_type();
foreach ($simplePie->get_items() as $key => $item) {
$item->get_date("Y-m-d H:i:s");
$item->get_id();
$item->get_title();
$item->get_content();
$item->get_description();
$item->get_category();
}
Memory debugging over 100 iterations (with different RSS feeds):
But when using $item->get_permalink()
, my memory debugging looks like this over 100 iterations (with different RSS feeds).
Code to produce problem:
foreach ($simplePie->get_items() as $key => $item) {
$item->get_date("Y-m-d H:i:s");
$item->get_id();
$item->get_title();
$item->get_permalink(); //This creates a memory leak
$item->get_content();
$item->get_description();
$item->get_category();
}
Things I've tried:
- Using
get_link
instead ofget_permalink
- Using
__destroy
as mentioned here (even though it should be fixed for 5.3)
Current debugging process:
I seem to have traced the problem down to SimplePie_Item::get_permalink
-> SimplePie_Item::get_link
-> SimplePie_Item::get_links
-> SimplePie_Item::sanitize
-> SimplePie::sanitize
-> SimplePie_Sanitize::sanitize
-> SimplePie_Registry::call
-> SimplePie_IRI::absolutize
as of now.
What can I do to fix this?
回答1:
This is actually not a memory leak, but rather static function caches that aren't being cleaned!
This is due to SimplePie_IRI::set_iri
(and set_authority
, and set_path
). They set a static $cache
variable, but they don't unset or clean this when a new instance of SimplePie
is created, which means the variables only gets bigger and bigger.
This can be fixed by changing
public function set_authority($authority)
{
static $cache;
if (!$cache)
$cache = array();
/* etc */
to
public function set_authority($authority, $clear_cache = false)
{
static $cache;
if ($clear_cache) {
$cache = null;
return;
}
if (!$cache)
$cache = array();
/* etc */
..etc in the following functions:
set_iri
,set_authority
,set_path
,
And adding a destructor to SimplePie_IRI
calling all the functions using a static cache, with a parameter of true
in $clear_cache, will work:
/**
* Clean up
*/
public function __destruct() {
$this->set_iri(null, true);
$this->set_path(null, true);
$this->set_authority(null, true);
}
Which will now result in no gain in memory consumption over time:
Git Issue
来源:https://stackoverflow.com/questions/14337179/why-am-i-getting-memory-leaks-in-simplepie-when-using-item-get-permalink