Управление памятью PHP

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

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

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

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

5 ответов


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

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

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


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


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

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

также, Как сказал Jauzsika, измените лимит памяти в своем php.Ини, хотя не делайте его слишком высоким. Если вам нужно больше, чем 256MB RAM, я бы предложил перейти на другой язык вместо PHP.


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

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

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


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

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