DOMDocument PHP Утечка памяти - PullRequest
9 голосов
/ 05 декабря 2011

При запуске PHP 5.3.6 под MAMP на MAC, использование памяти увеличивается каждые x вызовов (между 3 и 8), пока скрипт не умрет от исчерпания памяти. Как мне это исправить?

libxml_use_internal_errors(true);
while(true){
 $dom = new DOMDocument();
 $dom->loadHTML(file_get_contents('http://www.ebay.com/'));
 unset($dom);
 echo memory_get_peak_usage(true) . '<br>'; flush();
}

Ответы [ 4 ]

19 голосов
/ 05 декабря 2011

Использование libxml_use_internal_errors(true); подавляет вывод ошибок, но создает непрерывный журнал ошибок, который добавляется в каждый цикл.Либо отключите внутреннее ведение журнала и подавьте предупреждения PHP, либо очистите внутренний журнал на каждой итерации цикла следующим образом:

<?php
libxml_use_internal_errors(true);
while(true){
 $dom = new DOMDocument();
 $dom->loadHTML(file_get_contents('ebay.html'));
 unset($dom);
 libxml_use_internal_errors(false);
 libxml_use_internal_errors(true);
 echo memory_get_peak_usage(true) . "\r\n"; flush();
}
?>
2 голосов
/ 28 апреля 2012

Основываясь на ответе @ Tak и комментарии @FrancisAvila, я обнаружил, что этот фрагмент кода работает лучше для меня:

while (true)
{
    $dom = new DOMDocument();

    if (libxml_use_internal_errors(true) === true) // previous setting was true?
    {
        libxml_clear_errors();
    }

    $dom->loadHTML(file_get_contents('ebay.html'));
}

print_r(libxml_get_errors()); // errors from the last iteration are accessible

Это дает дополнительные преимущества: 1) не отбрасывать ошибки последнего анализа, если вам когда-либо понадобится получить к ним доступ через libxml_get_errors(), и 2) вызывать libxml_clear_errors() только при необходимости, так как libxml_use_internal_errors() возвращает предыдущее состояние настройки.

1 голос
/ 05 декабря 2011

Вы можете попытаться заставить сборщик мусора работать с gc_collect_cycles(), но в противном случае вам не повезло. PHP не предоставляет ничего для контроля использования внутренней памяти, не говоря уже о памяти, используемой библиотекой плагинов.

0 голосов
/ 05 декабря 2011

Локальное тестирование вашего скрипта дает тот же результат.Однако изменение file_get_contents() на локальный файл HTML приводит к последовательному использованию памяти.Может случиться так, что выходные данные на ebay.com меняются при каждом вызове X.

...