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

h2o*_*ooo 4 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();
}
Run Code Online (Sandbox Code Playgroud)

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

不使用get_permalink()的SimplePie

但是在使用时$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();
}
Run Code Online (Sandbox Code Playgroud)

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截至目前.

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

h2o*_*ooo 9

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

这是由于SimplePie_IRI::set_iri(和set_authority,和set_path).它们设置了一个静态$cache变量,但是当SimplePie创建一个新实例时,它们不会取消设置或清除它,这意味着变量只会变得越来越大.

这可以通过改变来解决

public function set_authority($authority)
{
    static $cache;

    if (!$cache)
        $cache = array();

    /* etc */
Run Code Online (Sandbox Code Playgroud)

public function set_authority($authority, $clear_cache = false)
{
    static $cache;
    if ($clear_cache) {
        $cache = null;
        return;
    }

    if (!$cache)
        $cache = array();

    /* etc */
Run Code Online (Sandbox Code Playgroud)

..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);
}
Run Code Online (Sandbox Code Playgroud)

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

SimplePie已修复

Git问题