Допустимый размер памяти исчерпан, но memory_get_peak_usage говорит об обратном

На моем сервере у меня есть следующая ошибка:

Разрешенный размер памяти 268435456 байт исчерпан

Это происходит в цикле (для каждого), и когда я проверяю использование памяти в цикле с помощью

memory_get_peak_usage();

Я получаю 7254128, который далеко не исчерпан 268435456!

Я проверил в нескольких местах, и использование памяти не увеличивается, поэтому я действительно не знаю, в чем проблема!

Тот же скрипт отлично работает на моем локальном компьютере, где я установил ограничение памяти только на 16M в моем файле php.ini.

Вот код, вызывающий проблему, но я думаю, что он не очень полезен, он взят из плагина формы с открытым исходным кодом question2answer:

foreach ($badges as $slug => $info) {
    $badge_name=qa_badge_name($slug);
    if(!qa_opt('badge_'.$slug.'_name')) 
            qa_opt('badge_'.$slug.'_name',$badge_name);
    $name = qa_opt('badge_'.$slug.'_name');
}

person darkheir    schedule 12.12.2012    source источник
comment
Итак... возможно, какой-то рекурсивный сбой либо в qa_opt, либо в qa_badge_slug?   -  person Wrikken    schedule 13.12.2012
comment
Я поместил это в пост, но не думаю, что это будет полезно, это из плагина, поэтому синтаксис особенный. И я знаю, что код не чистый, он не мой, но я пытаюсь заставить его работать!   -  person darkheir    schedule 13.12.2012
comment
@Wrikken это могло произойти во время foreach? потому что первый виток цикла работает хорошо, но ошибка возникает на втором. И это работает на моем локальном компьютере, это добавляет немного странности!   -  person darkheir    schedule 13.12.2012
comment
Что ж, тогда это не только может произойти, но и происходит внутри цикла foreach, не так ли? Это может быть проблема с данными в сочетании с логической ошибкой. Если у вас нет этой проблемы локально, я бы синхронизировал эти данные с данными на вашем сервере и посмотрел, что там происходит...   -  person Wrikken    schedule 13.12.2012
comment
Пытался синхронизировать все файлы и содержимое обеих баз данных, но все равно   -  person darkheir    schedule 13.12.2012
comment
Что ж, вы можете запустить трассировку xdebug, чтобы увидеть, что происходит прямо перед этим, что может пролить на это некоторый свет. Но одна из этих двух упомянутых функций, вероятно, вызывает проблемы.   -  person Wrikken    schedule 13.12.2012
comment
Какую версию PHP вы используете локально и удаленно?   -  person Arjan    schedule 13.12.2012
comment
@Arjan на локальном сервере 5.3.6, а на удаленном сервере 5.3.15.   -  person darkheir    schedule 13.12.2012


Ответы (1)


Я сильно подозреваю, что ваша проблема будет связана с «неправильной функцией» в стандартной библиотеке коннекторов MySQL. Когда из базы данных извлекается строка, содержащая поле «длинный BLOB-объект» или «длинный текст». Вместо выделения точного размера, необходимого для данных, библиотека MySQL пытается выделить наибольший размер, который может потребоваться для хранения строки. то есть 4 гигабайта памяти.

Самый простой способ исправить это — переключиться на использование соединителя MySQL ND, который не имеет этой «функции».

Массовое использование памяти PHP для SQL-запроса

Разрешенный размер памяти 67108864 байт исчерпан

Я проверяю использование памяти в цикле с помощью memory_get_peak_usage(); Я получаю 7254128, что далеко от исчерпанного 268435456!

Это правильно. Выделение памяти не выполняется, поэтому пиковое использование памяти никогда не показывает огромное выделение, как при использовании.

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

person Danack    schedule 16.01.2013