скрипту нехватает памяти

Статус
В этой теме нельзя размещать новые ответы.
ТС Я поступал проще я делил 1 большой скрипт на несколько мелких и потом по очереди они запускались через крон. 1й собирал контент второй обрабатывал 3й всё складывал в CMS
 
Во-первых, если лень ставить XDebug, есть две замечательные функции в самом php:
php.net/memory_get_usage
php.net/memory_get_peak_usage
Можешь понатыкать их вывод в разные места и посмотреть, как именно отжирается память.

Во-вторых, если ты парсишь DOM, память от них вполне возможно не освобождается по unset. Я с таким не раз сталкивался. В классе должно быть что-то типа $dom->clear() или типа такого, посмотри. Т.е. сначала clear(), потом unset.

В третьих, я вообще-то не понимаю, в чем тут в принципе может быть проблема. Ты парсишь файл, размер файла заранее известен. После парсинга создается массив, размер массива можно подсчитать (а хотя бы и через strlen(serialize($arr)); Прикинуть зависимость длины массива от размера исходного файла можно вполне, потренировавшись на небольших файликах. Потом соответственно можно легко вычислить максимальный размер файла, пригодного для парсинга твоим способом. Не устраивает размер - меняй алгоритм парсинга. Ну и плюс последи, чтоб у тебя этот массив был ОДИН, а то бывает сначала файл прочитают в строку, потом строку отматчат через preg_match_all() - при том, что $matches[0] вроде как и не нужны вовсе, а только [1] и т.д. Потом эти [1] и [2] копируют в другие массивы, по ним проходятся, конкатенируют обратно в строки... Итого у тебя один файл в том или ином виде в памяти сидит по 5 раз. Конечно никаких лимитов не хватит...
 
Могу посоветовать примерно такую архитектуру, благодаря которой когдато вписался в меморилимит.
1) $content=Получить_конттент любым способом();
2) $content=substr($content,$from,$to); где $from,$to получаются простым strpos() без регулярок. Этот пункт повторяешь столько раз, пока возможности substr не будут исчерпаны полностью. У меня шагов 7-8 было. После этого твой content уменьшится тем больше,чем мешьше удельный объем необходимой информации.
3) Дальше я выдирал обычной регуляркой;
4) Таким образом выдирается только!!! 1 "порция" нужной информации. Если этих "порций" в контенте несколько, не стесняйся использовать пункт 1 несколько раз. Это избавит тебя от необходимости держать куски контента в других перменных.
4)При возможности делай линейный алгоритм, без большого количества функций.


А вообще я 1 раз парсер писал на ASM, правда там был парсинг файлов.
 
провел у себя экспиримент, и выявил узкие места, все сделал просто создал маасив на начале пхп скрипта там занес первое значение memory_get_usage
далее ставил их там где надо потом вывел)
---
занятно,
но
-выявил что при учитожении класса память не освобождается, точнее то что освобождается слишом мало, а сама загруженная структура остается,
- чем больше инклудов тем больше расход
выявил это на классах, раньше иклудил все классы, теперь только по требованию (это сэкономило около 1 мб)
-очитска происходит не полнистью проводил тест на циклах, при удалении переменной вся память не особождается, свободно стаовится примерно 99%, видимо 1% занимает сам код, чем компактнее код тем меньше места занимает, коментарии не считаются)
- с обфускатом не пробовал возможно будет разница...
- так же не непотно как достигается весокая скорость работы фрейм ворком если у них инклудом тьма и расход памяти велик, в чем же их преимущество неясно, но проведу более детальных разбор на базе Zend FW)
- обидно то что нельзя скажем после выполения удлить функции или кслассы из памяти, не только нарущить ссылку с ними и свободить занимаемые переменные в нем, но и сам класс уничтожить осободив занимаемое место в ОП ) обидно но решения ненашел, теперь мне совмем неясны зачем ___unset destucit и тп_ ну кроме конструктора)
 
-выявил что при учитожении класса память не освобождается, точнее то что освобождается слишом мало, а сама загруженная структура остается,
Я тоже пробовал, там в другом фишка: при повторном выделении памяти под тот же объект (после unset) у тебя не отжирается новый кусок памяти, а используется тот, который якобы тогда "не освободился". Т.е. как я понял оно вроде как помечается как свободное, но VirtualFree() ему не делается - PHP предполагает, что "еще пригодится".

фрейм ворком если у них инклудом тьма и расход памяти велик, в чем же их преимущество неясно, но проведу более детальных разбор на базе Zend FW)

Проведи-проведи. ZF как раз отличный пример. include_once после каждых пяти строчек кода с try catch.. Там чувачки на славу ебанулись.
 
провел эксперимент на ZF
как и думал
-расход памяти для размещения кода в разы больше
-ни разу внутри не увидел изменения в меньшую сторону, только рост расхода, да при повторном обращении роста нет
- при на самом простом примере расход памяти составил 2,9 и это не использую СуБД ), у меня же мой мини фрейм ворк с плагинам и прочей голубой мутью занимает 2,2мб (вчера специально тестил загрузил данные везде с учетом автопостроения форм и запросов)
- боюсь даже смотреть монстра как Joomla )))) а теперь наверное глупая мысль сегодня, почему MODx является одним из немногих проектов который выдерживает нагрузки больших объемов, но при это не мало кушает памяти,
те если мыслить логически, то при 100 пользователях онлайн, лимит обычного хостера будет исчерпан, ну предположим что 100 человек обратилось в 1 и где секунду к сайту)
---
как вообще оценивают хостеры расход того или иного хоста
какими средствами под вин и линукс, думаю что это не просто смотрение на диспетчера задач=)... вот у меня на работе для этого есть тулза для HP это отдельная железка делает) есть ли программное решение.
------
все же жаль что PHP не все так хорошо как хотелось бы... хоть на яву и руби переходи ) там вроде нет таких заморочек
 
как вообще оценивают хостеры расход того или иного хоста
какими средствами под вин и линукс, думаю что это не просто смотрение на диспетчера задач=)

Не знаю что там в винде (виндовые хостеры обычно с .NET все, а там вообще черт ногу сломит), а юниксовые таки да, смотрят на 'ps ax', grep'ят его чем-нибудь и складывают в статистику. Так и работаем.. Есть пакеты которые делают это автоматом, munin например вообще очень много всего показывает - с графичками, удобно.. Но не в реальном времени. Хочешь в реальном - сам сиди в шелле и мониторь, благо там все понятно.

Просто необходимости как-то особой нету, выставил юзерам лимиты - и ебитесь как хотите. Если лимитов не хватает - или пишите чтоб увеличили (за $ обычно) или сами разбирайтесь, что у вас там эту память жрет. Хостеру лезть в хитросплетения юзерских скриптов (которые на любом языке вообще-то могут быть написаны) как то не комильфо. Я бы сам бежал от такого хостера, который по моим исходникам шарится..


все же жаль что PHP не все так хорошо как хотелось бы... хоть на яву и руби переходи ) там вроде нет таких заморочек

Да в PHP на самом деле все довольно хорошо. У Руби производительность намного хуже. Девелопить на ней быстрее - это да, а в плане потребления ресурсов она от PHP отличается очень сильно в худшую сторону.

Заботит производительность отдельных запросов - копай в сторону fcgi. Или вот node.js, к примеру. Совершенно фантастическая штука, спокойно держит 11000 одновременных запросов, тогда как на стандартном LAMP у меня 500-600. Но писать на асинхронных вызовах - это здорово мозги вывернуть надо.
 
появился еще 1 вопрос
"вроде как бы" php само это делает, но ...
вот небольшая функция
PHP:
/**
   * Открыть мета данные
   * @return array
   */
  function open($config, &$link=null) {
    if (($config['module'] != '') || (!empty($config['module']))):
      $this->path($config);
    endif;
    if (file_exists($this->module)):
      $metadata = null;
      include_once($this->module);
      $link = $metadata;
    //  $metadata = array();
      $metadata = null;
      unset($metadata);
    endif;
  }
теперь стоит ли делать следующие, все переменный которые явно не возвращаются и не являются ссылками, очищать (удалять)
PHP:
$config=null;
или же может
PHP:
$config=null;
unset($config);


проверял что данные не очищаются а висят до следующего вызова,
а если данных много...
при очистке происходит расход больше, но я пока тестил на малых объемах, где сама операция очистки занимает больше чем данные которые она удаляет


стоит ли так делать)
ваши комментарии...
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху