it-swarm.dev

Závažná chyba: Povolená velikost paměti 134217728 bajtů vyčerpaných (CodeIgniter + XML-RPC)

Mám spoustu systémů klientských prodejních míst (POS), které pravidelně zasílají nová data o prodeji do jedné centralizované databáze, která ukládá data do jedné velké databáze pro generování přehledů.

Klient POS je založen na PHPPOS a implementoval jsem modul, který používá standardní XML-RPC knihovnu k odesílání prodejních dat do služby. Serverový systém je postaven na CodeIgniter a používá knihovnu XML-RPC a XML-RPCS pro komponentu webservice. Kdykoliv pošlu mnoho prodejních dat (jen 50 řádků z prodejní tabulky a jednotlivé řádky z sales_items, které se vztahují ke každé položce v rámci prodeje), mám následující chybu:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 54 bytes)

128M je výchozí hodnota v php.ini, ale předpokládám, že se jedná o obrovské číslo, které se má zlomit. Ve skutečnosti jsem se dokonce pokusil nastavit tuto hodnotu na 1024M, a vše, co dělá, je trvat déle, než chyba.

Pokud jde o kroky, které jsem podnikl, zkusil jsem zakázat veškeré zpracování na straně serveru a zmanipuloval jsem ho, aby vrátil předpřipravenou odpověď bez ohledu na vstup. Domnívám se však, že problém spočívá ve skutečném zasílání údajů. Dokonce jsem se pokusil zakázat maximální dobu provádění skriptů pro PHP a stále chybí.

555
ArcticZero

Změna memory_limit podle ini_set('memory_limit', '-1'); je není správné řešení. Prosím, nedělejte to.

Kód PHP může mít někde únik paměti a říkáte serveru, aby používal pouze veškerou paměť, kterou chce. Neměli byste problém vůbec řešit. Pokud sledujete váš server, uvidíte, že nyní pravděpodobně používá většinu RAM a dokonce i přepíná na disk.

Pravděpodobně byste se měli pokusit sledovat kód, který je urážlivý, ve vašem kódu a opravit.

655
Jeff

ini_set('memory_limit', '-1'); přepíše výchozí limit paměti PHP .

200
Chris Lane

Správným způsobem je upravit soubor php.ini. Upravte memory_limit na požadovanou hodnotu.

Jak od vaší otázky, 128M (což je výchozí limit) byl překročen, takže tam je něco vážně špatně s vaším kódem, protože by to nemělo trvat tak moc.

Pokud víte, proč to trvá tak moc a chcete to nastavit memory_limit = 512M nebo vyšší a měli byste být dobří.

122
Basav

Přidělení paměti pro PHP lze nastavit trvale nebo dočasně.

Trvale

Přidělení paměti PHP můžete trvale změnit dvěma způsoby.

Pokud máte přístup ke svému souboru php.ini, můžete hodnotu memory_limit upravit podle své hodnoty.

Pokud nemáte přístup k vašemu souboru php.ini (a váš webhosting to povoluje), můžete přepsat paměť prostřednictvím souboru .htaccess. Přidejte php_value memory_limit 128M (nebo libovolné požadované přidělení).

Dočasný

Přidělení paměti můžete nastavit za letu ze souboru PHP. Jednoduše máte kód ini_set('memory_limit', '128M'); (nebo jakýkoliv požadovaný příděl). Omezení paměti můžete odebrat (ačkoli omezení počítače nebo instance může stále platit) nastavením hodnoty na hodnotu -1.

88
Umair Idrees

Je velmi snadné dostat únik paměti do skriptu PHP - zvláště pokud používáte abstrakci, například ORM. Zkuste použít Xdebug k profilování vašeho skriptu a zjistěte, kam se ta paměť dostala.

59
troelskn

Když přidávám do pole s polem array_Push 22,5 milionu záznamů, stále jsem dostával "vyčerpanou paměť" na přibližně 20M záznamů s použitím 4G jako limit paměti v php.ini. K opravě jsem přidal prohlášení

$old = ini_set('memory_limit', '8192M'); 

v horní části souboru. Teď všechno funguje dobře. Nevím, jestli php má únik paměti, to není moje práce, ani se o to nestarám. Prostě musím udělat svou práci a to fungovalo.

Program je velmi jednoduchý:

$fh = fopen($myfile);
while (!feof($fh)) {
      array_Push($file, stripslashes(fgets($fh)));
}  
fclose($fh);

Závažná chyba ukazuje na řádek 3, dokud se nezvýší limit paměti, který chybu odstranil.

52
JamesAD-0

Dostal jsem tuto chybu, a to i s memory_limit nastaveným v php.ini a hodnotou, která se správně čte s phpinfo().

Změnou z tohoto:

memory_limit=4G

K tomuto:

memory_limit=4096M

Tento problém byl odstraněn v PHP 7.

45
Danny Beckett

Když se zobrazí výše uvedená chyba - zejména pokud (tried to allocate __ bytes) je nízká hodnota, může to být indikátor nekonečné smyčky, jako je funkce, která sama volá bez cesty ven:

function exhaustYourBytes()
{
    return exhaustYourBytes();
}
21
Kristen Waite

Po povolení těchto dvou řádků.
Začalo to fungovat

; Determines the size of the realpath cache to be used by PHP. This value should
; be increased on systems where PHP opens many files to reflect the quantity of
; the file operations performed.
; http://php.net/realpath-cache-size
realpath_cache_size = 16k

; Duration of time, in seconds for which to cache realpath information for a given
; file or directory. For systems with rarely changing files, consider increasing this
; value.
; http://php.net/realpath-cache-ttl
realpath_cache_ttl = 120

18

Můžete to správně opravit změnou paměti memory_limit na fastcgi/fpm

$vim /etc/php5/fpm/php.ini

Změňte paměť jako z 128 na 512 viz níže

; Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit = 128M

na

; Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit = 512M
17
Derick Fynn

Kořenový adresář vašeho webu: -

ini_set('memory_limit', '1024M');
15
Gaurang P

Namísto změny hodnoty memory_limit ve vašem souboru php.ini, pokud existuje část kódu, která by mohla používat mnoho paměti, můžete před spuštěním této sekce odstranit memory_limit a poté jej nahradit.

$limit = ini_get('memory_limit');
ini_set('memory_limit', -1);
// ... do heavy stuff
ini_set('memory_limit', $limit);
12
mykeels

V aplikaci Drupal 7 můžete upravit limit paměti v souboru settings.php umístěném ve složkách web/výchozí složka. Kolem linky 260 uvidíte toto:

ini_set('memory_limit', '128M');

I když jsou vaše nastavení php.ini dostatečně vysoká, nebudete moci spotřebovat více než 128 MB, pokud to není nastaveno v souboru Drupal settings.php.

11
LK7889

Pro uživatele Drupalu je tato odpověď Chrisa Laneho na:

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

funguje, ale musíme to dát hned po otevření

<?php

tag v souboru index.php v kořenovém adresáři vašeho webu.

11
sigmapi13

Změňte limit paměti z php.ini file a restartujte Apache. Po restartu spusťte phpinfo (); funkce z libovolného souboru php pro potvrzení změny paměti memory_limit.

memory_limit = -1

limit paměti -1 znamená, že není nastaven žádný limit paměti, který je nyní maximální.

10
Hasib Kamal

PHP 5.3+ umožňuje změnit limit paměti umístěním souboru .user.ini do složky public_html. Jednoduše vytvořte výše uvedený soubor a zadejte do něj následující řádek:

memory_limit = 64M

Někteří hostitelé cPanel tuto metodu akceptují.

7
Sabi

Pro ty, kteří si poškrábají chlupy, aby zjistili, proč by tato malá funkce měla způsobit únik paměti, někdy malou chybou, funkce začne rekurzivně nazývat navždy.

Například třída proxy, která má stejný název pro funkci objektu, který bude proxy server proxy používat.

class Proxy {

    private $actualObject;

    public function doSomething() {

        return $this->actualObjec->doSomething();
    }
}   

Někdy můžete zapomenout na to, aby ten malý skutečný člen a protože Proxy vlastně má tuto metodu, PHP vám nedává žádnou chybu a pro velkou třídu to může být skryto před očima pro pár minut, abyste zjistili, proč uniká paměť.

7
madz

CRASH stránka?  enter image description here

(Stává se, když má MySQL dotaz na velké řádky, ve výchozím nastavení je parametr momory_limit nastaven na malý, což bylo pro hardware bezpečnější)

Před zvýšením php.ini můžete zkontrolovat existující stav paměti vašeho systému.

# free -m
             total       used       free     shared    buffers     cached
Mem:         64457      63791        666          0       1118      18273
-/+ buffers/cache:      44398      20058
Swap:         1021          0       1021

Zde jsem ji zvětšil následovně a pak service httpd restart opravil problém stránky CRASH.

# grep memory_limit /etc/php.ini
memory_limit = 512M
6
YumYumYum

Měl jsem chybu níže, zatímco jsem běžel na datasetu menší, než pracoval dříve.

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4096 bytes) in C:\\workspace\image_management.php on line 173

Vzhledem k tomu, že mě sem hledání viny přivedlo, myslel jsem, že zmíním, že to není vždy technické řešení, ale něco jednoduššího. V mém případě to byl Firefox. Než jsem program spustil, používal již 1 157 MB.
Ukázalo se, že jsem sledoval 50minutové video trochu po čase v průběhu několika dnů a že se to pokazilo. Je to druh opravy, kterou odborníci opravují, aniž by o tom přemýšleli, ale pro mě se to vyplatí.

4
M61Vulcan

Pokud používáte VPS (Virtual Private Server) s napájením WHM, můžete zjistit, že nemáte oprávnění k úpravě PHP.INI přímo; systém to musí udělat. V ovládacím panelu hostitele WHM přejděte do Konfigurace služby> PHP Konfigurační editor, upravte paměť:

Updating memory_limit on WHM 11.48.4

3
Janckos

Spuštění tohoto skriptu (například případ cron): php5 /pathToScript/info.php vytvoří stejnou chybu.

Správný způsob: php5 -cli /pathToScript/info.php

3
ratm

Považuji to za užitečné, pokud zahrnuli nebo vyžadujete:
dbconnection.php , _functions.php v souborech, které jsou skutečně zpracovány,
namísto zahrnutí do záhlaví. Což je samo o sobě.

Takže pokud vaše záhlaví a zápatí je zahrnuta, jednoduše zahrnout všechny své funkční soubory před záhlaví je zahrnuta.

3
Kerim

V mém případě se jednalo o krátkou otázku, jak byla funkce napsána. Únik paměti může být způsoben přiřazením nové hodnoty vstupní proměnné funkce, např .:

/**
* Memory leak function that illustrates unintentional bad code
* @param $variable - input function that will be assigned new value
* @return null
**/
function doSomehting($variable){
    $variable = 'set value';
    // or
    $variable .= 'set value';
}
1
Dmitriy Kravchuk

Použití yield může být také řešením https://www.php.net/manual/en/language.generators.syntax.php

Namísto změny souboru PHP.ini pro větší paměťové úložiště může někdy problém implementovat yield uvnitř smyčky. Jaký výtěžek je namísto dumpingu všech dat najednou, čte jeden po druhém ukládání spoustu využití paměti.

0
LukeDS

Stačí přidat ini_set ('memory_limit', '-1'); v horní části webové stránky. A můžete nastavit paměť podle vašich potřeb na místě -1 až 16M atd.

0