Я пытаюсь отследить использование памяти сценария, который обрабатывает URL. Основная идея состоит в том, чтобы проверить, что существует разумный буфер прежде, чем добавить другой URL к ВИХРЕВОМУ много обработчику. Я использую 'прокручивающееся ВИХРЕВОЕ' понятие, которое обрабатывает данные URL, когда много обработчик работает. Это означает, что я могу сохранить соединения N активными путем добавления нового URL от пула каждый раз, когда существующий URL обрабатывает и удален.
Я использовал memory_get_usage()
с некоторыми положительными результатами. Добавление real_usage
флаг помог (не действительно ясный на различии между 'системной' памятью и 'emalloc' памятью, но система показывает большее число). memory_get_usage()
действительно растет, поскольку URL добавляются тогда вниз, поскольку набор URL истощается. Однако я просто превысил 32M предел с моей последней проверкой памяти, являющейся ~18M.
Я опрашиваю использование памяти каждый раз ВИХРЕВЫЕ много сигналы, которые возвратил запрос. Так как несколько запросов могут возвратиться одновременно, существует шанс, набор URL возвратил данные одновременно и на самом деле перешел использование памяти это 14M. Однако, если memory_get_usage()
точно, я предполагаю, что это - то, что происходит.
[Обновление: Должен был запустить больше тестов прежде, чем попросить, чтобы я предположил, увеличил предел памяти php (но оставил 'безопасную' сумму тем же в сценарии), и использование памяти, как сообщается спрыгивало ниже моего самостоятельно назначенного предела 25M к по 32M. Затем как ожидалось медленно сползал вниз как URL где не добавленный. Но я оставлю на виду вопрос: действительно ли это - правильный способ сделать это?]
Я могу доверять memory_get_usage()
таким образом? Есть ли лучшие альтернативные методы для получения использования памяти (я видел, что некоторые сценарии анализируют вывод команд оболочки)?
Можно использовать keep-lines
для получения желаемого, копирования и последующей отмены. Напротив, есть также линии очистки
, чтобы избавиться от линий, которые вы не хотите.
Не определяйте сопоставление столбцов, которые требуется загрузить по запросу. Затем настройте параметры, описанные в разделе Отложенная загрузка столбцов , с помощью объекта mapper
. Измененный код:
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class SomeClass(Base):
__tablename__ = 'some_table'
id = Column(Integer, primary_key=True)
name = Column(String(50))
#big_name = Column(String(500))
SomeClass.__table__.append_column(Column('big_name', String(500)))
SomeClass.__mapper__.add_property('big_name', deferred(SomeClass.__table__.c.big_name))
Выполнение этого тестового кода
c = session.query(SomeClass).first()
# here SQL is loading all configured properties, but big_name
print "c: ", c
# only here another SQL request is made to load the property
print "big_name: ", c.big_name
приводит к извлечению журнала:
... INFO sqlalchemy.engine.base.Engine.0x...77d0 SELECT some_table.id AS some_table_id, some_table.name AS some_table_name
FROM some_table
LIMIT 1 OFFSET 0
... INFO sqlalchemy.engine.base.Engine.0x...77d0 SELECT some_table.big_name AS some_table_big_name
FROM some_table
WHERE some_table.id = ?
-121--4213388- real _ usage
работает следующим образом:
Менеджер памяти Zend не использует системный malloc для каждого необходимого блока. Вместо этого он выделяет большой блок системной памяти (с приращениями 256K, может быть изменен путем установки переменной среды ZEND _ MM _ SEG _ SIZE
) и управляет ею внутри системы. Итак, существует два вида использования памяти:
Любой из них может быть возвращен memory _ get _ usage ()
. Какой из них более полезен для вас, зависит от того, что вы ищете. Если вы ищете возможности оптимизации кода в определенных частях, «внутренний» может оказаться более полезным для вас. Если вы отслеживаете использование памяти в глобальном масштабе, «real» будет более полезным. memory _ limit
ограничивает «реальное» число, так что, как только все блоки, разрешенные пределом, взяты из системы и менеджер памяти не может выделить запрошенный блок, там выделение не удается. Обратите внимание, что «внутреннее» использование в этом случае может быть меньше предела, но выделение все равно может завершиться неудачей из-за фрагментации.
Кроме того, если вы используете средство отслеживания внешней памяти, вы можете установить это
переменная среды USE _ ZEND _ ALLOC = 0
, которая отключит вышеупомянутый механизм и заставит механизм всегда использовать malloc ()
. Это имело бы гораздо худшую производительность, но позволяет использовать средства слежения malloc.
См. также статью об этом менеджере памяти , он также содержит примеры кода.
Я также предполагаю, что memory_get_usage()
безопасен, но я думаю, вы можете сравнить оба метода и решить для себя, вот функция, которая разбирает системные вызовы:
function Memory_Usage($decimals = 2)
{
$result = 0;
if (function_exists('memory_get_usage'))
{
$result = memory_get_usage() / 1024;
}
else
{
if (function_exists('exec'))
{
$output = array();
if (substr(strtoupper(PHP_OS), 0, 3) == 'WIN')
{
exec('tasklist /FI "PID eq ' . getmypid() . '" /FO LIST', $output);
$result = preg_replace('/[\D]/', '', $output[5]);
}
else
{
exec('ps -eo%mem,rss,pid | grep ' . getmypid(), $output);
$output = explode(' ', $output[0]);
$result = $output[1];
}
}
}
return number_format(intval($result) / 1024, $decimals, '.', '');
}
Ну, у меня никогда не было проблем с памятью в моих PHP-скриптах, поэтому я не думаю, что смогу может очень помочь в поиске причины проблемы, но я могу порекомендовать вам использовать ускоритель PHP, вы заметите серьезное увеличение производительности и уменьшение использования памяти. Вот список ускорителей и статья, в которой сравниваются некоторые из них (производительность в 3 раза выше по сравнению с любым из них)
Тестам уже 2 года, но вы имеете представление об увеличении производительности .
При необходимости вы также можете увеличить лимит памяти в PHP, если у вас все еще есть проблемы даже с ускорителем. Откройте свой php.ini и найдите:
memory_limit = 32M;
и просто немного увеличьте его.