Отслеживание использования памяти в PHP

Я пытаюсь отследить использование памяти сценария, который обрабатывает 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() таким образом? Есть ли лучшие альтернативные методы для получения использования памяти (я видел, что некоторые сценарии анализируют вывод команд оболочки)?

32
задан Tim Lytle 18 February 2010 в 17:19
поделиться

3 ответа

Можно использовать keep-lines для получения желаемого, копирования и последующей отмены. Напротив, есть также линии очистки , чтобы избавиться от линий, которые вы не хотите.

-121--2366117-

Не определяйте сопоставление столбцов, которые требуется загрузить по запросу. Затем настройте параметры, описанные в разделе Отложенная загрузка столбцов , с помощью объекта 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 ) и управляет ею внутри системы. Итак, существует два вида использования памяти:

  1. Сколько памяти обработчик взял из ОС («реальное использование»)
  2. Сколько этой памяти фактически использовалось приложением («внутреннее использование»)

Любой из них может быть возвращен memory _ get _ usage () . Какой из них более полезен для вас, зависит от того, что вы ищете. Если вы ищете возможности оптимизации кода в определенных частях, «внутренний» может оказаться более полезным для вас. Если вы отслеживаете использование памяти в глобальном масштабе, «real» будет более полезным. memory _ limit ограничивает «реальное» число, так что, как только все блоки, разрешенные пределом, взяты из системы и менеджер памяти не может выделить запрошенный блок, там выделение не удается. Обратите внимание, что «внутреннее» использование в этом случае может быть меньше предела, но выделение все равно может завершиться неудачей из-за фрагментации.

Кроме того, если вы используете средство отслеживания внешней памяти, вы можете установить это переменная среды USE _ ZEND _ ALLOC = 0 , которая отключит вышеупомянутый механизм и заставит механизм всегда использовать malloc () . Это имело бы гораздо худшую производительность, но позволяет использовать средства слежения malloc.

См. также статью об этом менеджере памяти , он также содержит примеры кода.

45
ответ дан 27 November 2019 в 20:56
поделиться

Я также предполагаю, что 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, '.', '');
}
8
ответ дан 27 November 2019 в 20:56
поделиться

Ну, у меня никогда не было проблем с памятью в моих PHP-скриптах, поэтому я не думаю, что смогу может очень помочь в поиске причины проблемы, но я могу порекомендовать вам использовать ускоритель PHP, вы заметите серьезное увеличение производительности и уменьшение использования памяти. Вот список ускорителей и статья, в которой сравниваются некоторые из них (производительность в 3 раза выше по сравнению с любым из них)

Wikipedia List

Benchmark

Тестам уже 2 года, но вы имеете представление об увеличении производительности .

При необходимости вы также можете увеличить лимит памяти в PHP, если у вас все еще есть проблемы даже с ускорителем. Откройте свой php.ini и найдите:

memory_limit = 32M;

и просто немного увеличьте его.

-5
ответ дан 27 November 2019 в 20:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: