2010-07-26 3 views
7

У меня есть несколько трудоемких и (потенциально) интенсивных в памяти функций в моем веб-приложении LAMP. Большинство из этих функций будут выполняться каждую минуту через cron (в некоторых случаях задание cron будет выполнять несколько экземпляров этих функций).Управление памятью PHP

Поскольку память конечна, я не хочу сталкиваться с проблемами, когда я пытаюсь выполнить функцию, с которой среда больше не может работать. Что такое хороший подход при решении проблем с памятью?

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

Кроме того, я не хочу сталкиваться с проблемой, когда определенная функция каким-то образом получает приоритет выполнения над другими функциями. Если какой-либо приоритет дается, я бы хотел каким-то образом контролировать это.

+1

Что еще более важно, почему вы делаете Cronjob каждые ** минуту **? Частью проблемы может быть то, что cron является simpyl, пытающимся сделать слишком много сразу. Если бы вы могли объяснить проблему и предлагаемое решение, мы могли бы дать более качественные ответы на вашу конкретную проблему с памятью. Существуют разные подходы к решению различных проблем. Много данных из базы данных? Плоский файл? Просто тонна математических расчетов? У каждого из них будут свои собственные этапы оптимизации. Пожалуйста, определите, какова ваша проблема, чтобы мы могли дать правильный ответ :). – CogitoErgoSum

+0

Я думаю, вам нужно быть более описательным и заявить, что вы делаете в этой работе cron. Очевидная экономия не будет загружать огромные файлы в память для обработки, использовать потоковые функции, то же самое с вытягиванием большого набора результатов БД в память, использовать курсор для работы с набором записей, а не вытягивать все данные в массив и т. Д. –

ответ

1

вы можете изучить технологии кеширования, такие как APC, которые позволяют записывать материал прямо в ОЗУ, чтобы вы могли быстро получить доступ к нему, который вам нужен, если вы не хотите многократно выполнять дорогостоящие задачи, такие как запросы mysql.

пример для кэширования, о котором я мог думать, это то, что вы можете кэшировать электронные письма, а не возвращать их снова и снова с сервера электронной почты. basicaly ram caching - очень полезный метод, если у вас есть вещи в вашем скрипте, которые вы хотите сохранить в следующий раз при выполнении скрипта, но если ваш скрипт делает уникальные вещи каждый раз, когда он выполняется, это было бы бесполезно.также как для contoll вы можете вызвать memory_get_usage() для каждого исполнения скрипта и записать это значение в кэш-память apc, чтобы каждый cron мог восстановить это значение и посмотреть, достаточно ли свободного для него свободного места.

Что касается среднего использования, вы можете написать массив с последним разрешением, скажем, 100 выполнение функций, и когда вы снова вызовете эту функцию, он сможет apc_fetch из ram и вычислить среднее использование памяти для этой функции, а затем сравните ее с тем, сколько ram используется сейчас, а затем решает начать. кроме того, он мог бы записать эту оценку в текущую переменную использования памяти, чтобы предотвратить запуск других сценариев. в конце этой функции вы снова вычитаете эту сумму из переменной. ТЛ; др: взгляда в apc_fetch, apc_store и memory_get_usage функции

+0

Задачи, связанные с областью памяти, не связаны с MySQL. Большинство из них имеет какое-то отношение к обработке изображений, обработке PDF-файлов, загрузке и выгрузке файлов с FTP-серверов, отправке и извлечению электронных писем и т. Д. – StackOverflowNewbie

+0

€: я расширил свой ответ для лучшей читаемости –

0

Вы можете узнать, сколько памяти в данный момент используется вашим скриптом, используя memory_get_usage Но вы не можете определить, какая ваша следующая функция понадобится перед ее выполнением. Вы можете видеть только после выполнения, используя memory_get_usage. Тем не менее вы можете сохранить память, в которой ваша функция использовала последние времена в базе данных, и вычислять ее со средней суммой памяти.

Что касается приоритета выполнения, я не думаю, что это можно определить с помощью PHP. Apache (или любой другой веб-сервер, который вы используете) генерирует несколько процессов и расписания операционной системы, которые будут выполняться в каком порядке.

+0

'memory_limit' определяет, сколько памяти может обрабатывать каждый php-процесс. Он находится в файле php.ini. По умолчанию это 8 или 16 МБ. Вы можете изменить это в любое время на большее значение, пока у вас не будет достаточно системной памяти (+ swap). – Jauzsika

0

Отличительной чертой вашей проблемы может быть тот факт, что вы делаете cron каждую минуту? Почему бы не установить несколько флагов, так что только один экземпляр этого cron запускается до того, как другой выполнит полную логику? т. е. создать плоский файл, который был удален в конце cron, чтобы действовать как «блокировка». Это гарантирует, что один процесс cron будет полностью завершен, прежде чем какие-либо другие будут продвигаться вперед. Тем не менее, я настоятельно призываю вас сослаться на мой комментарий к вашему сообщению, чтобы я и другие могли дать вам более солидные советы.

+1

Предположим, что у меня есть законная причина для запуска работы cron каждую минуту. – StackOverflowNewbie

0

Попробуйте оптимизировать свои алгоритмы. Как ...

  • Как только вы закончите с переменной, вы должны уничтожить ее, если она вам больше не понадобится.
  • Закройте соединения MySQL после того, как вы закончили с ними.
  • Используйте рекурсию.

Также, как сказал Яузика, измените свой предел памяти на вашем php.ini, хотя и не делайте его слишком высоким. Если вам требуется более 256 МБ ОЗУ, я бы предложил перейти на другой язык вместо PHP.

+0

Я не думаю, что вы можете указать произвольный предел в 256 МБ, учитывая, что он не описал, что делает его код. –

+0

У вас наверняка есть точка. – sonikarc

+0

Все переменные уничтожены, все соединения DB закрыты, рекурсия не является опцией. 256mb является произвольным. Нет никаких оснований для переключения языков. Мне просто нужен способ убедиться, что я не случайно использую слишком много памяти. – StackOverflowNewbie

0

В вашем положении, я бы тебе демон вместо того, чтобы полагаться на хронах. Демон мог следить за очередью и знать количество запущенных дочерних процессов. Управление несколькими процессами определенно не является самой большой силой php, но you can do it. Груша даже включает пакет System_Daemon.

Ваш демон может использовать memory_get_usage и вызывать free, uptime и друзей, чтобы снизить количество рабочих, чтобы они соответствовали системным условиям.

У меня нет прямого опыта с этим, и я не был бы слишком удивлен, если бы демон, написанный на PHP, постепенно просочился в память. Но если это приемлемо медленно, cron может так часто цитировать демона ...

+0

... Я думаю, что дочерние процессы, вероятно, будут иметь для вызова 'memory_get_usage' и передачи результата родительскому объекту ... или, возможно, родитель может обратиться к' ps' или 'top' ... – grossvogel

Смежные вопросы