Дозволений об'єм пам'яті 33554432 байтів вичерпано (намагався виділити 43148176 байт) у php


279

Це повідомлення про помилку подається, є якісь пропозиції?

Дозволений об'єм пам'яті 33554432 байтів вичерпано (намагався виділити 43148176 байт) у php


5
Збільште максимальний ліміт пам’яті до 64 Мб у вашому файлі php.ini. Пошук у Google Але я можу запитати, чому ви намагаєтеся виділити стільки пам’яті? У якому рядку коду він не працює?

1
Що робить сценарій, коли він не працює? Ви можете опублікувати код?
Ніл Ейткен

3
Схоже на дуже величезний txt-файл.
macbirdie

10
Зазвичай ви читаєте файли, які мають потенційно великий або довільний розмір один рядок, перезаписуючи попередню пам'ять рядка з кожним прочитаним рядком. Або ви можете просто захотіти хвостик або очолити файл, щоб отримати останні записи. Посилення розподілу пам'яті у міру зростання файлу - це не відповідь.
екернер

Відповіді:


318

Нарешті я знайшов відповідь:

Просто додайте цей рядок нижче до рядка отримання помилки у вашому файлі

ini_set('memory_limit', '-1');

Це займе необмежене використання сервера пам'яті, це працює чудово.

Дякуємо, що надали друзям пропозиції.


125
Ви все ще повинні перевірити, чому пам'ять вичерпана. Можливо, вам не потрібно читати весь файл, можливо, читайте його послідовно.
macbirdie

8
- @panidarapu та @Don Jones: Залежно від обсягу пам'яті та способу використання цього сценарію, можна дозволити таким чином дозволити змінити використання пам'яті. Дон, у вашому випадку ви, ймовірно, можете розбити подачу на менші шматки та проаналізувати те, що вам потрібно. Радий, що це працює, але будьте обережні.
анонімний боягуз

5
Ця пропозиція спрацювала для мене. Динамічно збільшується ліміт пам’яті в сценарії здійснюється за допомогою функції ini_set (): ini_set ('memory_limit', '128M');
менте

37
Хлопці, будь ласка, не ходіть на це швидке виправлення. Це може завдати вам біль у довгостроковій перспективі. Як хороший програміст, ви повинні з'ясувати причину цього споживання пам'яті та збільшення, як потрібно, замість того, щоб зберігати її UNLIMITED.
Sumoanand

113
Вау, ця відповідь, яка настільки широко підтримується, здається мені справді поганою практикою. -1!
Ambidex

59

Ось два простих способи збільшення ліміту на спільний хостинг:

  1. Якщо у вас є доступ до файлу PHP.ini, змініть рядок у PHP.ini Якщо в рядку відображається 32M, спробуйте 64M: memory_limit = 64M ; Maximum amount of memory a script may consume (64MB)

  2. Якщо у вас немає доступу до PHP.ini, спробуйте додати це до файлу .htaccess: php_value memory_limit 64M


47

Ваш сценарій використовує занадто багато пам'яті. Це часто може траплятися в PHP, якщо у вас є цикл, який закінчився контролем, і ви створюєте об'єкти або додаєте до масивів на кожному проході циклу.

Перевірте на нескінченні петлі.

Якщо це не проблема, спробуйте допомогти PHP, знищивши об'єкти, якими ви закінчили, встановивши їх на нуль. напр.$OldVar = null;

Перевірте код, де помилка насправді трапляється. Чи очікуєте ви, що цей рядок буде виділяти величезну кількість пам'яті? Якщо ні, спробуйте з’ясувати, що пішло не так ...


3
У мене була така точна проблема - виявилося, що я ненавмисно створив рекурсивну функцію - і, таким чином, вона втратила пам'ять у будь-який випадковий час під час виконання коду. У мене це перевернуло тепер найефективніший у світі код пам'яті, створений під час полювання на витік пам'яті.
Кріс Селбекк

1
Заради інших, хто буде ганяти кролика в норі. Вчення в Symfony, я думаю, має проблему з монологією, і коли є виняток із PDO, він створить нескінченний цикл винятків, оскільки він спробує виключення для виключення, приховавши справжню проблему (у моєму випадку пошкоджений файл db).
Десіслав камени

39

Виконуємо:

ini_set('memory_limit', '-1');

ніколи не є доброю. Якщо ви хочете прочитати дуже великий файл, найкраще копіювати його побіжно. Спробуйте наступний код для найкращої практики.

$path = 'path_to_file_.txt';

$file = fopen($path, 'r');
$len = 1024; // 1MB is reasonable for me. You can choose anything though, but do not make it too big
$output = fread( $file, $len );

while (!feof($file)) {
    $output .= fread( $file, $len );
}

fclose($file);

echo 'Output is: ' . $output;

6
Не можу повірити всім цим людям, які рекомендують встановити memory_limit на -1 ... Божевільна річ робити на виробничому сервері. Дякую за набагато більш чисте рішення.
JohnWolf

2
Перебуваючи в "кращій практиці", добре закрити обробник файлів після whileциклу:fclose($file)
kodeart

2
@assetCorp Як це допомагає, за умови, якщо у файлу є, наприклад, 100MiB, а ліміт пам’яті PHP все ще встановлено на 32 МБ. Ви читаєте його захищеними фрагментами 1MiB, але потім додаєте їх до змінної, яка збирається використовувати всю наявну пам'ять, як тільки цикл досягне 31. ітерації. Як це краще? Тільки виведення фрагментів аналогічно, щоб не вимагати їх зберігання в одній змінній, допоможе вирішити проблему.
helvete

17

На жаль, легко програмувати в PHP таким чином, що споживає пам'ять швидше, ніж ви усвідомлюєте. Копіювання рядків, масивів та об’єктів замість використання посилань зробить це, хоча PHP 5 повинен робити це більш автоматично, ніж у PHP 4. Але поводження з вашими наборами даних усього за кілька кроків також є марним порівняно з обробкою найменшої логічної одиниці зараз. Класичний приклад - це робота з великими наборами результатів із бази даних: більшість програмістів витягують весь набір результатів у масив, а потім переходять на нього один чи кілька разів foreach(). Набагато ефективніше пам'ять використовувати while()цикл для отримання та обробки одного рядка за один раз. Те саме стосується обробки файлу.


Здається, досить вірогідно, що саме це і робить.
Kzqai

13

Якщо ви хочете читати великі файли, вам слід читати їх побіжно, а не читати їх відразу.
Це проста математика: якщо ви читаєте файл величиною 1 Мб одночасно, для зберігання даних одночасно потрібно щонайменше 1 Мб пам'яті.

Тому вам слід читати їх побіжно за допомогою fopen& fread.


1
Вирішили це, використовуючи:$fh = fopen($folder.'/'.$filename, "rb") or die(); $buffer = 1024*1024; while (!feof($fh)) { print(fread($fh, $buffer)); flush(); } fclose($fh);
Кай Ноак

12

Я зіткнувся з тією ж проблемою в php7.2 з laravel 5.6. Я просто збільшую кількість змінної memory_limit = 128Mв php.ini в міру того, як вимагають мої програми. Це може бути 256M / 512M / 1048M ..... Зараз це працює чудово.


6

У мене також були ті ж проблеми, шукав файли phpinfo.ini, php.ini або .htaccess безрезультатно. Нарешті я переглянув деякі файли php, відкрив їх і перевірив коди всередині пам’яті. Нарешті, це рішення було тим, з чим я вийшов, і це спрацювало на мене. Я використовував wordpress, тому це рішення може працювати лише для проблеми обмеження розміру пам'яті wordpress. Моє рішення, відкрийте файл default-constants.php у папці / public_html / wp- include. Відкрийте цей файл у редакторі коду та знайдіть налаштування пам’яті під wp_initial_constantsобластю або просто Ctrl + F, щоб знайти слово «пам'ять». Там ви будете приїжджати WP_MEMORY_LIMITі WP_MAX_MEMORY_LIMIT. Просто збільште його, в моєму випадку це було 64 Мб, я збільшив його до 128 МБ, а потім до 200 МБ.

// Define memory limits.
if ( ! defined( 'WP_MEMORY_LIMIT' ) ) {
    if ( false === wp_is_ini_value_changeable( 'memory_limit' ) ) {
        define( 'WP_MEMORY_LIMIT', $current_limit );
    } elseif ( is_multisite() ) {
        define( 'WP_MEMORY_LIMIT', '200M' );
    } else {
        define( 'WP_MEMORY_LIMIT', '128M' );
    }
}

if ( ! defined( 'WP_MAX_MEMORY_LIMIT' ) ) {
    if ( false === wp_is_ini_value_changeable( 'memory_limit' ) ) {
        define( 'WP_MAX_MEMORY_LIMIT', $current_limit );
    } elseif ( -1 === $current_limit_int || $current_limit_int > 268435456 /* = 256M */ ) {
        define( 'WP_MAX_MEMORY_LIMIT', $current_limit );
    } else {
        define( 'WP_MAX_MEMORY_LIMIT', '256M' );
    }
}

До речі, не робіть наступного коду, оскільки це погана практика:

ini_set('memory_limit', '-1');

1
Працює для веб-сайтів Wordpress, де доступ недоступний для файлів .htaccess та php.ini. +1
Мустафа сабір

Я б сказав, що зміна цих обмежень на "основний" файл WordPress насправді не є хорошою ідеєю; ви можете дуже легко додати ці обмеження wp-config.phpзамість них, коли вони не будуть перезаписані майбутніми оновленнями WordPress. Крім того , кілька плагінів безпеки (наприклад, WordFence, наприклад) буде скаржитися , якщо «основні» файли WordPress змінюються ...
Гвінет Llewelyn

1
@GwynethLlewelyn Я не знаю, як це зробити, чи можете ви це детальніше розробити?
гараччі

1
Про ... просто редагувати wp-config.php. І додати два рядки (я .e define( 'WP_MEMORY_LIMIT', '200M' );і define( 'WP_MAX_MEMORY_LIMIT', '256M' );. В відміну від файлів на «основний» WP (а саме, все під wp-includes), які будуть перезаписані поновлення WP, wp-config.phpне буде - це є саме для точна мета перевищення констант WP!
Гвінет Левелін

1
"погана практика" ситуативна. -1добре для короткочасних процесів. Наприклад, контейнер php builder, який використовується для запуску тестів одиниць або встановлення композиторів / тощо. Просто не запускайте свій виробничий майданчик з таким налаштуванням.
emmdee

5

Ви можете збільшити пам'ять, дозволену php-скрипту, виконавши наступний рядок над усіма кодами сценарію:

ini_set('memory_limit','-1'); // enabled the full memory available.

А також де виділити небажані змінні в сценарії.

Перевірте цю бібліотеку PHP: Звільнення пам'яті за допомогою PHP



3

Я зауважую, що багато відповідей просто намагаються збільшити об'єм пам'яті, наданий сценарію, який має своє місце, але частіше за все це означає, що щось занадто ліберальне з пам'яттю через небаченого обсягу або розміру. Очевидно, якщо ваш автор не є сценарієм, то на волю автора, якщо ви не почуваєте себе амбітним :) Документи PHP навіть кажуть, що проблеми з пам'яттю пов'язані з " погано написаними сценаріями "

Слід зазначити, що ini_set('memory_limit', '-1');(без обмеження) може викликати нестабільність сервера як 0 bytes free = bad things. Натомість знайдіть розумний баланс за тим, що намагається зробити ваш сценарій, і кількістю наявної пам’яті на машині.

Кращий підхід: якщо ви автор сценарію (або амбітний), ви можете налагодити подібні проблеми з пам'яттю за допомогою xdebug . Остання версія (2.6.0 - випущена 2018-01-29) повернула профайл пам'яті, який показує, на які функціональні дзвінки витрачається велика кількість пам'яті. Це розкриває проблеми в сценарії, які інакше важко знайти. Зазвичай неефективність знаходиться в циклі, який не очікує обсягу, який він отримує, але кожен випадок залишатиметься читачем як вправа :)

Документація xdebug є корисною, але вона зводиться до 3 кроків:

  1. Встановити - Доступно через apt-getта yumін
  2. Налаштуйте його - xdebug.ini: xdebug.profiler_enable = 1,xdebug.profiler_output_dir = /where/ever/
  3. Перегляньте профілі в такому інструменті, як QCacheGrind , KCacheGrind

2

Якщо ви намагаєтеся прочитати файл, це займе пам'ять у PHP. Наприклад, якщо ви намагаєтесь відкрити та прочитати MP3-файл (наприклад, $ data = file (" http://mydomain.com/path/sample.mp3 "), він все це перетягне в пам'ять .

Як пропонує Нельсон, ви можете працювати над збільшенням максимального обмеження пам'яті, якщо вам потрібно використовувати стільки пам’яті.


2

У нас була подібна ситуація, і ми спробували дати відповіді у верхній частині відповідей ini_set ('memory_limit', '-1'); і все працювало нормально, стиснуті файли зображень перевищували 1 Мб до КБ.


1

Пишіть

ini_set('memory_limit', '-1');

у вашому index.php вгорі після відкриття тегу php


1

Я отримав те саме повідомлення про помилку після переходу на нову тему в Wordpress. PHP працював у версії 5.3, тому я перейшов на 7.2. Це вирішило питання.


1

Якщо ви користуєтесь спільним хостингом, ви не зможете застосувати збільшення в обмеженні розміру php.

Просто перейдіть до свого cpanel та оновіть свою PHP-версію до версії 7.1 та вище, тоді ви готові йти.


0

Користувачі wordpress додають рядок:

@ini_set('memory_limit', '-1');

у wp-settings.php, яку ви можете знайти в кореневій папці, встановленій wordpress


0

Я не поновлював хостинг, і база даних була лише для читання. Joomla потрібно було написати сеанс і не зміг цього зробити.


0

У мене був той самий випуск, який виконував php у командному рядку. Нещодавно я змінив файл php.ini і помилився під час зміни php.ini

Це для php7.0

шлях до php.ini, де я помилився: /etc/php/7.0/cli/php.ini

Я поставив memory_limit = 256(що означає 256 bytes)
замість memory_limit = 256M(що означає 256 Mega bytes).

; Максимальний об'єм пам'яті, який може споживати сценарій (128 МБ)
; http://php.net/memory-limit
memory_limit = 128M

Як тільки я це виправив, мій процес почав нормально працювати.



-1

якщо ви використовуєте laravel, тоді використовуйте ці способи

public function getClientsListApi(Request $request){ print_r($request->all()); //for all request print_r($request->name); //for all name }

замість

public function getClientsListApi(Request $request){ print_r($request); // it show error as above mention }

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.