Запустив 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(); }
Использование 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(); } ?>
в<?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(); } ?>
с<?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(); } ?>
Вы можете попробовать заставить сборщик мусора работать с gc_collect_cycles()
, но в противном случае вам не повезло. PHP не раскрывает ничего, что могло бы контролировать его использование внутренней памяти, не говоря уже о памяти, используемой библиотекой плагинов.
Основываясь на ответе @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()
возвращает предыдущее состояние настройки.
Тестирование вашего скрипта локально дает тот же результат. Однако изменение file_get_contents()
в локальном HTML-файле обеспечивает согласованное использование памяти. Возможно, выход из ebay.com меняет каждый X-вызов.