Я использую SimplePie с PHP 5.3 (с включенным gc) для анализа моих RSS-каналов. Это работает хорошо и без проблем, когда вы делаете что-то вроде следующего:
$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("Ymd H:i:s"); $item->get_id(); $item->get_title(); $item->get_content(); $item->get_description(); $item->get_category(); }
Отладка памяти более 100 итераций (с различными RSS-каналами):
Но при использовании $item->get_permalink()
моя отладка памяти выглядит примерно 100 итераций (с разными RSS-каналами).
Код для создания проблемы :
foreach ($simplePie->get_items() as $key => $item) { $item->get_date("Ymd 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(); }
Вещи, которые я пробовал :
get_link
вместо get_permalink
__destroy
как указано здесь (хотя это должно быть исправлено для 5.3) Текущий процесс отладки :
Я, кажется, проследил проблему до 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
на данный момент.
Что я могу сделать, чтобы исправить это?
На самом деле это не утечка памяти, а статические кеши, которые не очищаются!
Это связано с SimplePie_IRI::set_iri
(и set_authority
и set_path
). Они устанавливают статическую переменную $cache
, но они не отменят или не очищают ее при создании нового экземпляра SimplePie
, что означает, что переменные становятся все больше и больше.
Это можно исправить, изменив
public function set_authority($authority) { static $cache; if (!$cache) $cache = array(); /* etc */
в
public function set_authority($authority, $clear_cache = false) { static $cache; if ($clear_cache) { $cache = null; return; } if (!$cache) $cache = array(); /* etc */
..etc в следующих функциях:
set_iri
, set_authority
, set_path
, И добавление деструктора в SimplePie_IRI
вызывающее все функции с использованием статического кеша с параметром true
в $ clear_cache, будет работать:
/** * Clean up */ public function __destruct() { $this->set_iri(null, true); $this->set_path(null, true); $this->set_authority(null, true); }
Это не приведет к увеличению потребления памяти с течением времени:
Git Issue