Почему я получаю утечки памяти в SimplePie при использовании $ item-> get_permalink ()?

Я использую 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-каналами):

SimplePie без использования get_permalink ()

Но при использовании $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(); } 

Утечка памяти SimplePie get_permalink

Вещи, которые я пробовал :

  • Использование 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_iriset_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); } 

Это не приведет к увеличению потребления памяти с течением времени:

Исправлено SimplePie

Git Issue