使用$ item-> get_permalink()时,为什么我在SimplePie中出现内存泄漏?

时间:2013-01-15 11:56:10

标签: php memory-leaks simplepie

我正在使用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("Y-m-d H:i:s");
    $item->get_id();
    $item->get_title();
    $item->get_content();
    $item->get_description();
    $item->get_category();
}

内存调试超过100次迭代(使用不同的 RSS源):

SimplePie without using get_permalink()

但是当使用$item->get_permalink()时,我的内存调试看起来超过100次迭代(使用不同的 RSS源)。

产生问题的代码

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();
}

SimplePie get_permalink memory leak

我尝试过的事情

  • 使用get_link代替get_permalink
  • 使用上面提到的__destroy here(即使它应该针对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截至目前。

我该怎么做才能解决这个问题?

1 个答案:

答案 0 :(得分:9)

这实际上不是内存泄漏,而是静态函数缓存,而不是正在清理!

这归因于SimplePie_IRI::set_iri(以及set_authorityset_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 */

..等在以下功能中:

  • set_iri
  • set_authority
  • set_path

SimplePie_IRI添加析构函数,使用静态缓存调用所有函数,在$ clear_cache中使用true参数,将起作用:

/**
 * Clean up
 */
public function __destruct() {
    $this->set_iri(null, true);
    $this->set_path(null, true);
    $this->set_authority(null, true);
}

现在,这将导致内存消耗不会随着时间的推移而增加:

SimplePie fixed

Git Issue