PHP не хватает памяти, но памяти достаточно

Я запускаю свой PHP-скрипт, и ему нужно explode большой файл .txt (около 1 ГБ), но он каждый раз терпит неудачу с сообщением об ошибке Out of memory.

Out of memory (allocated 1168297984) (tried to allocate 268435464 bytes)

Я попытался изменить свой php.ini на 2048M, а также попытался добавить ini_set('memory_limit','2048M'); в свой скрипт, но это все еще происходит. Кроме того, я не использую Apache или какой-либо другой сервер, PHP используется только для обработки файлов.

print("Starting: ". ini_get("memory_limit")."\n");
$usage = memory_get_usage()/1000000;
print("Usage: ".$usage."\n");

Когда я пытаюсь отладить использование памяти, я получаю вот это.

Starting: 2048M
Usage: 693.059752
mmap() failed: [12] Cannot allocate memory
mmap() failed: [12] Cannot allocate memory
PHP Fatal error:  Out of memory (allocated 1168297984) (tried to allocate 268435464 bytes)

Кроме того, в системе имеется более 1 ГБ свободной памяти.


person Omega    schedule 10.12.2018    source источник
comment
Есть ли у ОС ограничения на выделение памяти для пользователя?   -  person Lucas Holt    schedule 10.12.2018
comment
Просто из-за того, что вы установили ограничение памяти на большое число, системе, на которой работает ваш код, может не хватить памяти для вашего сценария. Например. в среде общего хостинга вы можете быть ограничены хостинговой компанией, чтобы один пользователь не использовал все ресурсы на машине, установив ограничение памяти на абсурдно большое число. Возможно, вы захотите проверить функции генератора и файловые потоки, чтобы они работали с объемом оперативной памяти, который у вас есть (который, по-видимому, не превышает 1 ГБ).   -  person SeinopSys    schedule 10.12.2018
comment
@LucasHolt Для пользователя не должно быть ограничений по памяти, так как я работаю как пользователь root в Debian 9.   -  person Omega    schedule 10.12.2018
comment
@SeinopSys Я не работаю на виртуальном хостинге.   -  person Omega    schedule 10.12.2018
comment
В этом случае системные процессы могут использовать оставшуюся доступную память ровно настолько, чтобы PHP не мог выделить этот дополнительный гигабайт. Такие инструменты, как htop и команда free, помогут вам выяснить, так ли это.   -  person SeinopSys    schedule 10.12.2018
comment
Читайте файл по частям, не тратьте ОЗУ, лол. Кроме того, ini_set не является гарантией, проверьте его ответ, чтобы убедиться, что вы увеличили лимит. Но, честно говоря, ваша проблема заключается в вашей идее прочитать весь файл с одного выстрела. Дружище, сделай цикл и прочитай файл шаг за шагом. Это совсем не сложно.   -  person user1597430    schedule 10.12.2018
comment
Свободной памяти достаточно (около 1230 МБ), а скрипт пытается использовать только 268 МБ.   -  person Omega    schedule 10.12.2018
comment
То, что вы делаете, является распространенной ошибкой разработчиков PHP. Никогда не загружайте в память весь большой файл. Вам доступно множество вариантов: sitepoint.com/performant- чтение-больших-файлов-php   -  person Raptor    schedule 10.12.2018
comment
Посмотрите на вывод: php -i | grep -i memory_limit. Это дает вам текущий memory_limit. Настройки для CLI и WEB могут отличаться, поэтому я предлагаю эту командную строку. Как только вы убедитесь, что в php env установлен правильный memory_limit, посмотрите на free -m, который даст вам, сколько памяти в настоящее время доступно для вашей системы. Эти команды применимы для ОС на базе Linux.   -  person Nikola Petkanski    schedule 10.12.2018
comment
@Raptor был прав, хотя я до сих пор не знаю, почему сценарию не хватило памяти, поскольку в системе 2 ГБ ОЗУ, а 1,5 ГБ можно использовать бесплатно. В конце концов, чтение файла построчно решило проблему.   -  person Omega    schedule 11.12.2018
comment
@Raptor был прав, хотя я до сих пор не знаю, почему сценарию не хватило памяти, поскольку в системе 2 ГБ ОЗУ, а 1,5 ГБ можно использовать бесплатно. В конце концов, чтение файла построчно решило проблему.   -  person Omega    schedule 11.12.2018
comment
Для программистов всегда старайтесь оптимизировать использование памяти, чтобы иметь лучшую производительность.   -  person Raptor    schedule 12.12.2018