Dozwolony rozmiar pamięci 33554432 bajtów wyczerpany (próbował przydzielić 43148176 bajtów) w php

279

Ten komunikat o błędzie jest wyświetlany, jakieś sugestie?

Dozwolony rozmiar pamięci 33554432 bajtów wyczerpany (próbował przydzielić 43148176 bajtów) w php

panidarapu
źródło
5
Zwiększ maksymalny limit pamięci do 64 MB w pliku php.ini. Wyszukiwarka Google Ale czy mogę zapytać, dlaczego próbujesz przydzielić tyle pamięci? W której linii kodu nie działa?
1
Co robi skrypt, gdy zawiedzie? czy możesz opublikować kod?
Neil Aitken
3
Wygląda jak bardzo duży plik txt.
macbirdie
10
Zwykle odczytujesz pliki o potencjalnie dużej lub dowolnej wielkości po jednym wierszu na raz, zastępując poprzednią pamięć linii przy każdym czytaniu. Lub możesz po prostu ogonić lub przewinąć plik, aby uzyskać najnowsze wpisy. Zwiększenie alokacji pamięci w miarę wzrostu pliku nie jest odpowiedzią.
ekerner

Odpowiedzi:

318

W końcu znalazłem odpowiedź:

Po prostu dodaj ten wiersz poniżej, zanim pojawi się błąd w pliku

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

Zajmie to nieograniczone wykorzystanie pamięci przez serwer, działa dobrze.

Dzięki za sugestie przyjaciół.

panidarapu
źródło
125
Nadal powinieneś sprawdzić, dlaczego pamięć jest wyczerpana. Może nie musisz czytać całego pliku, może sekwencyjnie.
macbirdie
8
- @panidarapu i @Don Jones: W zależności od ilości pamięci i sposobu użycia tego skryptu zezwolenie na zmianę wykorzystania pamięci w ten sposób może być niebezpieczne. Don, w twoim przypadku możesz prawdopodobnie podzielić kanał na mniejsze części i przeanalizować to, czego potrzebujesz. Cieszę się, że to działa, ale bądź ostrożny.
anonimowy tchórz
5
Ta sugestia zadziałała dla mnie. Dynamicznie zwiększający się limit pamięci w skrypcie odbywa się za pomocą funkcji ini_set (): ini_set ('memory_limit', '128M');
mente
37
Chłopaki, proszę, nie wybierajcie tej szybkiej poprawki. Na dłuższą metę może cię zranić. Jako dobry programista powinieneś znaleźć przyczynę tego zużycia pamięci i zwiększyć ją w miarę potrzeb, zamiast ją zachować UNLIMITED.
Sumoan i
113
Wow, ta ogromnie pozytywna odpowiedź wydaje mi się naprawdę złą praktyką. -1!
Ambidex
59

Oto dwie proste metody zwiększenia limitu hostingu współdzielonego:

  1. Jeśli masz dostęp do pliku PHP.ini, zmień wiersz w PHP.ini Jeśli Twój wiersz pokazuje 32M, wypróbuj 64M: memory_limit = 64M ; Maximum amount of memory a script may consume (64MB)

  2. Jeśli nie masz dostępu do PHP.ini, spróbuj dodać to do pliku .htaccess: php_value memory_limit 64M

Haider Abbas
źródło
47

Twój skrypt zużywa zbyt dużo pamięci. Może się to często zdarzyć w PHP, jeśli masz pętlę, która wymknęła się spod kontroli i tworzysz obiekty lub dodajesz tablice przy każdym przejściu pętli.

Sprawdź nieskończone pętle.

Jeśli to nie jest problem, spróbuj pomóc PHP, niszcząc obiekty, na których skończyłeś, ustawiając je na zero. na przykład.$OldVar = null;

Sprawdź kod, w którym rzeczywiście występuje błąd. Czy spodziewałbyś się, że linia ta alokuje ogromną ilość pamięci? Jeśli nie, spróbuj dowiedzieć się, co poszło nie tak ...

Rik Heywood
źródło
3
Miałem właśnie ten problem - okazało się, że przypadkowo utworzyłem funkcję rekurencyjną - i dlatego zabrakło pamięci w dowolnym momencie podczas wykonywania kodu. Miałem tę zaletę, że mam teraz najbardziej efektywny na świecie kod pamięci, stworzony w celu wykrycia wycieku pamięci.
Kris Selbekk
1
Ze względu na innych, którzy będą ścigać królika w dziurze. Doctrine w Symfony i myślę, że ma problem z monologiem, a gdy występuje wyjątek PDO, utworzy nieskończoną pętlę wyjątków, ponieważ spróbuje wyjątku dla wyjątku, ukrywając w ten sposób prawdziwy problem (w moim przypadku uszkodzony plik db).
Desislav Kamenov
39

Robić :

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

nigdy nie jest dobre. Jeśli chcesz przeczytać bardzo duży plik, najlepszym rozwiązaniem jest kopiowanie go krok po kroku. Wypróbuj poniższy kod dla najlepszych praktyk.

$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;
Delali
źródło
6
Nie mogę uwierzyć wszystkim tym, którzy zalecają ustawienie memory_limit na -1 ... Szalona rzecz do zrobienia na serwerze produkcyjnym. Dzięki za znacznie czystsze rozwiązanie.
JohnWolf
2
Podczas „najlepszej praktyki” dobrze jest zamknąć procedurę obsługi plików po whilepętli:fclose($file)
kodeart
2
@assetCorp Jak to pomaga, pod warunkiem że plik ma na przykład 100 MB, a limit pamięci PHP jest nadal ustawiony na 32 MiB. Czytasz to przez bezpieczne fragmenty 1 MB, ale następnie dołączasz do zmiennej, która będzie wykorzystywać całą dostępną pamięć, gdy pętla osiągnie 31. iterację. Jak to jest lepsze? Tylko wyprowadzenie fragmentów w podobny sposób, aby nie wymagały przechowywania ich wszystkich w jednej zmiennej, pomogłoby rozwiązać problem.
helvete
17

Niestety programowanie w PHP jest łatwe w sposób, który zużywa pamięć szybciej, niż się wydaje. Zrobią to kopiowanie ciągów, tablic i obiektów zamiast korzystania z referencji, chociaż PHP 5 powinno to robić bardziej automatycznie niż w PHP 4. Jednak radzenie sobie z zestawem danych w kilku krokach jest również marnotrawstwem w porównaniu do przetwarzania najmniejszej jednostki logicznej na czas. Klasycznym przykładem jest praca z dużymi zestawami wyników z bazy danych: większość programistów pobiera cały zestaw wyników do tablicy, a następnie zapętla ją raz lub więcej razy foreach(). O wiele bardziej wydajna pamięć jest użycie while()pętli do pobierania i przetwarzania jednego wiersza na raz. To samo dotyczy przetwarzania pliku.

staticsan
źródło
Wydaje się całkiem prawdopodobne, że to właśnie to robi.
Kzqai,
13

Jeśli chcesz czytać duże pliki, powinieneś czytać je krok po kroku zamiast od razu.
To prosta matematyka: jeśli odczytujesz 1 MB dużego pliku naraz, potrzeba co najmniej 1 MB pamięci w tym samym czasie do przechowywania danych.

Więc powinieneś czytać je krok po kroku za pomocą fopen& fread.

Gumbo
źródło
1
Rozwiązano to, używając:$fh = fopen($folder.'/'.$filename, "rb") or die(); $buffer = 1024*1024; while (!feof($fh)) { print(fread($fh, $buffer)); flush(); } fclose($fh);
Kai Noack
12

Ten sam problem napotkałem w php7.2 z laravel 5.6. Po prostu zwiększam ilość zmiennych memory_limit = 128Mw php.ini zgodnie z wymaganiami moich aplikacji. Może to być 256M / 512M / 1048M ..... Teraz działa dobrze.

Ziaur Rahman
źródło
6

Miałem również ten sam problem, szukałem plików phpinfo.ini, php.ini lub .htaccess bezskutecznie. W końcu przejrzałem niektóre pliki php, otworzyłem je i sprawdziłem, czy w kodzie nie ma pamięci. Wreszcie znalazłem to rozwiązanie i zadziałało dla mnie. Korzystałem z wordpress, więc to rozwiązanie może działać tylko w przypadku problemu z limitem wielkości pamięci wordpress. Moje rozwiązanie, otwórz plik default-constants.php w folderze / public_html / wp-zawiera . Otwórz ten plik za pomocą edytora kodu i znajdź ustawienia pamięci w wp_initial_constantszakresie lub po prostu Ctrl + F, aby znaleźć słowo „pamięć”. Tam przyjdziesz WP_MEMORY_LIMITi WP_MAX_MEMORY_LIMIT. Po prostu go zwiększ, w moim przypadku było to 64 MB, zwiększyłem go do 128 MB, a następnie do 200 MB.

// 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' );
    }
}

Przy okazji, nie rób następującego kodu, ponieważ to zła praktyka:

ini_set('memory_limit', '-1');
garakchy
źródło
1
Działa na stronach Wordpress, gdzie dostęp nie jest dostępny dla plików .htaccess i php.ini. +1
Mustafa sabir
Powiedziałbym, że zmiana tych limitów w „podstawowym” pliku WordPress nie jest dobrym pomysłem; możesz więc bardzo łatwo dodać te limity, wp-config.phpzamiast których zostaną one zastąpione przez przyszłe aktualizacje WordPress. Ponadto kilka wtyczek bezpieczeństwa (na przykład WordFence) będzie narzekać, jeśli zostaną zmienione „podstawowe” pliki WordPress ...
Gwyneth Llewelyn
1
@GwynethLlewelyn Nie wiem jak to zrobić, czy możesz to rozwinąć, proszę?
garakchy
1
Oh ... tylko edit wp-config.php. I dodać dwie linie tam (i .e define( 'WP_MEMORY_LIMIT', '200M' );i define( 'WP_MAX_MEMORY_LIMIT', '256M' );. W przeciwieństwie do plików na „core” WP (mianowicie, wszystko pod wp-includes), które zostaną zastąpione przez rozbudowę WP, wp-config.phpnie będzie - to tam właśnie dla dokładny cel zastąpienia stałych WP!
Gwyneth Llewelyn
1
„zła praktyka” ma charakter sytuacyjny. -1nadaje się do krótkotrwałych procesów. Na przykład kontener konstruktora php używany do uruchamiania testów jednostkowych lub instalator instaluje / etc. Po prostu nie uruchamiaj witryny produkcyjnej z takim ustawieniem.
emmdee
5

Możesz zwiększyć pamięć dozwoloną dla skryptu php, wykonując następujący wiersz ponad wszystkimi kodami w skrypcie:

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

A także dezaktywuj niechciane zmienne w skrypcie.

Sprawdź bibliotekę php: Zwalnianie pamięci za pomocą PHP

Sanjay Kumar NS
źródło
4
ini_set('memory_limit', '-1');
Nnh Nguyễn Thế
źródło
3
@Pang ini_set ('memory_limit', '-1');
DIGITALCRIMINAL
3

Zauważam, że wiele odpowiedzi po prostu próbuje zwiększyć ilość pamięci przeznaczonej dla skryptu, który ma swoje miejsce, ale najczęściej oznacza to, że coś jest zbyt liberalne w stosunku do pamięci z powodu nieprzewidzianej ilości lub wielkości. Oczywiście, jeśli nie jesteś autorem skryptu, jesteś na łasce autora, chyba że czujesz się ambitny :) Dokumenty PHP twierdzą nawet, że problemy z pamięcią wynikają z „ źle napisanych skryptów

Należy wspomnieć, że ini_set('memory_limit', '-1');(bez ograniczeń) może powodować niestabilność serwera as 0 bytes free = bad things. Zamiast tego znajdź rozsądną równowagę między tym, co skrypt próbuje zrobić, a ilością dostępnej pamięci na komputerze.

Lepsze podejście: jeśli jesteś autorem skryptu (lub ambitnego), możesz debugować takie problemy z pamięcią za pomocą xdebug . Najnowsza wersja (2.6.0 - wydana 29.01.2018) przywróciła profilowanie pamięci, które pokazuje, które wywołania funkcji zużywają duże ilości pamięci. Ujawnia problemy w skrypcie, które w innym przypadku byłyby trudne do znalezienia. Zwykle nieefektywności występują w pętli, która nie oczekuje wielkości, którą otrzymuje, ale każdy przypadek pozostawi czytelnikowi jako ćwiczenie :)

Dokumentacja xdebug jest pomocna, ale sprowadza się do 3 kroków:

  1. Zainstaluj - dostępne za pośrednictwem apt-geti yumitp
  2. Skonfigurować go - xdebug.ini: xdebug.profiler_enable = 1,xdebug.profiler_output_dir = /where/ever/
  3. Wyświetl profile w narzędziu takim jak QCacheGrind , KCacheGrind
SeanDowney
źródło
2

Jeśli próbujesz odczytać plik, zajmie to pamięć w PHP. Na przykład, jeśli próbujesz otworzyć i odczytać plik MP3 (np. $ Data = plik („ http://mydomain.com/path/sample.mp3 ”), wszystko to zapisze w pamięci .

Jak sugeruje Nelson, możesz pracować nad zwiększeniem maksymalnego limitu pamięci, jeśli faktycznie chcesz zużywać tyle pamięci.

Beau Simensen
źródło
2

Mieliśmy podobną sytuację i wypróbowaliśmy podane na początku odpowiedzi ini_set ('memory_limit', '-1'); i wszystko działało dobrze, skompresowane pliki obrazów większe niż 1 MB do KB.

dynamiczny przepływ
źródło
1

pisać

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

w index.php u góry po otwarciu tagu php

Prafull
źródło
1

Otrzymałem ten sam komunikat o błędzie po przejściu na nowy motyw w Wordpress. PHP działało w wersji 5.3, więc przełączyłem się na 7.2. To naprawiło problem.

DavGarcia
źródło
1

Jeśli korzystasz z hostingu współdzielonego, nie będziesz w stanie wymusić przyrostu limitu rozmiaru php.

Po prostu przejdź do swojego panelu i zaktualizuj wersję php do wersji 7.1 lub nowszej, a następnie możesz zacząć.

successtar
źródło
0

użytkownicy wordpress dodają wiersz:

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

w wp-settings.php, który można znaleźć w folderze głównym zainstalowanego Wordpress

Praveesh P.
źródło
0

Nie odnowiłem hostingu, a baza danych była tylko do odczytu. Joomla musiał napisać sesję i nie mógł tego zrobić.

Alberto M.
źródło
0

Miałem ten sam problem, co uruchamianie php w linii poleceń. Ostatnio miałem zmiany pliku php.ini i popełniłem błąd podczas zmiany php.ini

To jest dla php7.0

ścieżka do php.ini, w której popełniłem błąd: /etc/php/7.0/cli/php.ini

Ustawiłem memory_limit = 256(co oznacza 256 bytes)
zamiast memory_limit = 256M(co oznacza 256 Mega bytes).

; Maksymalna ilość pamięci, którą skrypt może zużyć (128 MB)
; http://php.net/memory-limit
memory_limit = 128M

Po poprawieniu mój proces zaczął działać poprawnie.

theBuzzyCoder
źródło
0

Uruchom to polecenie w katalogu głównym Magento php -d memory_limit=4G bin/magento

Mohammed Muzammil
źródło
-1

jeśli używasz laravel, użyj tych sposobów

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

zamiast

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

Ajay
źródło