![]() |
Модераторы: skyboy, MoLeX, Aliance, ksnk |
![]() ![]() ![]() |
|
Psytodelist |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 5.3.2010 Репутация: нет Всего: нет |
Здравствуйте! Есть класс для создания xml-карты сайта:
При сканировании ссылок больших сайтов, скрипт упирается в memory_limit, в этот момент приблизительно выходит спарсено около 5000 ссылок (128М), увеличил до (500М) - 21000 ссылок. Когда я пользовался простым curl, парсил большие каталоги, то подобного постоянного роста RAM я не замечал. Данные заносились в БД. Тут же мы видем, что данные сохраняются в переменной. Именно это вызывает рост потребляемой оперативной памяти или что-то другое? Посоветуйте, пожалуйста, как оптимизировать данный класс. Благодарю. Это сообщение отредактировал(а) Psytodelist - 6.5.2012, 22:18 |
|||
|
||||
Wolf1994 |
|
||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1701 Регистрация: 5.10.2004 Репутация: нет Всего: 29 |
Можно узнать, закомментировав сохранение данных:
То же можно записывать в переменную, а в SQL - после выполенения класса. Это сообщение отредактировал(а) Wolf1994 - 7.5.2012, 11:36 |
||||||
|
|||||||
Wolf1994 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1701 Регистрация: 5.10.2004 Репутация: нет Всего: 29 |
Размер ссылки почти всегда не больше четверти килобайта. 21000 / 4 = 5 Мб. Ошибка в том, что скрипт обрабатывает новые ссылки, не закончив обработку уже имеющихся. То есть, одновременно создаёт очень много запросов через cURL. |
|||
|
||||
Wolf1994 |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1701 Регистрация: 5.10.2004 Репутация: нет Всего: 29 |
Решение.
multi_curl($new_links); вызывать после каждого выполнения multi_curl (), при условии, что массив не пустой, очищая $new_links перед обращением:
|
||||
|
|||||
Psytodelist |
|
||||||||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 5.3.2010 Репутация: нет Всего: нет |
- это вообще вызывается по завершении программы, идет форматирование массива ссылок в XML
Что именно записывать в переменную? Зачем? Это счетчик для AJAX, чтобы видеть прогресс в реальном времени. Забыл дописать WHERE uniqid='$uniqid' , но это не страшно. Добавлено через 2 минуты и 8 секунд
Спасибо хоть за попытку помочь, а-то гуры-партизаны или их вообще тут нет. |
||||||||||||
|
|||||||||||||
Fortop |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2200 Регистрация: 13.11.2007 Где: Донецк Репутация: 1 Всего: 42 |
Psytodelist, лень
Проблема собственно в том, что не очищается какая-то из переменных в процессе циклов. А искать ее желания нет ![]() Попробуйте делать unset объектам связанным с запросами после каждых 5000 (или сколько у вас там) ссылок. -------------------- Мир это Я. Живее всех живых. |
|||
|
||||
Wolf1994 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1701 Регистрация: 5.10.2004 Репутация: нет Всего: 29 |
Потому и зачеркнул ответ (надо было стереть, наверно). 21000 UPDATE'ов не займут памяти, но немного (в зависимости от "железа" и типа таблицы) нагрузят систему без особой на то необходимости (для AJAX'а хватит и записи в файл и не на каждой итерации).
Вопрос не имеет отношения к уровню владения языком, а связан с алгоритмом, который создаёт многоуровневую параллельную обработку, вместо последовательной. Имел в виду, что не знаю, как пересоздавать массив при объектно-ориентированном стиле. |
|||
|
||||
Psytodelist |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 5.3.2010 Репутация: нет Всего: нет |
Wolf1994, я приблизительно понял в чем причина.
Проштудировал весь код memory_get_usage() и выяснил, что память занимают переменные, которые получают результат от curl_exec() и curl_multi_exec() . Т.е. переменные $page = curl_exec($curl); и $multi_curl = curl_multi_exec($multi_curl_handler, $active); А это - целые страницы... Теперь попробую как-то это дело исправить. ![]() Это сообщение отредактировал(а) Psytodelist - 7.5.2012, 17:11 |
|||
|
||||
Wolf1994 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1701 Регистрация: 5.10.2004 Репутация: нет Всего: 29 |
Да, из-за того, что каждая ссылка ведёт к созданию новых cURL запросов, которые создают под-запросы и так до бесконечности (в зависимости от структуры сайта и количества ссылок) - поэтому выделятся память под всё это и на стороне cURL и на PHP: под переменные, которые получают по нему страницы. |
|||
|
||||
Psytodelist |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 5.3.2010 Репутация: нет Всего: нет |
Походу ему все-равно на то, что я поставил unset-ы curl_multi_close($multi_curl_handler); unset($multi_curl, $content); $this->parse_content($page); unset($page); ![]() |
||||
|
|||||
Wolf1994 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1701 Регистрация: 5.10.2004 Репутация: нет Всего: 29 |
Потому что unset'ы срабатывают после вложенного запроса. То есть, $content через $this->parse_content($content); сначала передаётся в функцию parse_content, которая снова обращается к функции multi_curl и только по возвращению из последней происходит unset переданной переменной. |
|||
|
||||
Psytodelist |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 5.3.2010 Репутация: нет Всего: нет |
Ага, точно. Исправить это надежды нет? Добавлено через 4 минуты и 53 секунды strlen-ом проверил переменную $content. Именно она, зараза, кушает оперативку. И как её ансетить при устовии многопоточной рекурсии, если можно это так назвать, я не знаю ![]() |
|||
|
||||
Psytodelist |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 5.3.2010 Репутация: нет Всего: нет |
unset($page);
в конце скрипта - помогает, а unset($content); - нет unset($page); удаляет самое первое обращение к странице посредством простого курла. А когда я пишу unset($content); он не поймет же. Или поймет и-то в том цикле и-то если успеет закончится рекурсия. ![]() Это сообщение отредактировал(а) Psytodelist - 7.5.2012, 18:18 |
|||
|
||||
Wolf1994 |
|
||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1701 Регистрация: 5.10.2004 Репутация: нет Всего: 29 |
Есть, изменив параллельную работу на последовательную. Не проверял, но логику можно понять. Ключевые изменения:
Это сообщение отредактировал(а) Wolf1994 - 7.5.2012, 18:21 |
||||||
|
|||||||
Psytodelist |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 5.3.2010 Репутация: нет Всего: нет |
в конце $this->parse_content() unset($GLOBALS['content'][$uniqcontentid]); не помогло ![]() |
|||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | PHP: Для профи | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |