# memory_limit és Out-of-Memory: mi történik belül

> A PHP Out of Memory érthetően: hogyan számol a memory_limit, mi történik belül megszakításkor, és mit jelent ez a CVE-2026-109618 és a szerverei számára.

Forrás: https://phpsos.de/hu/php/out-of-memory/  
Állapot: 2026. 10. 25.  
Szolgáltató: PHP SOS, PHP-vészhelyzeti segítség és szerverbiztonság. Azonnali segítség WhatsAppon: https://wa.me/491736494914?text=%C3%9Cdv%C3%B6zl%C3%B6m%2C%20PHP%20SOS%21%20Seg%C3%ADts%C3%A9gre%20van%20sz%C3%BCks%C3%A9g%C3%BCnk%20a%20PHP-szerver%C3%BCnkkel.%20C%C3%A9g%3A%20%E2%80%A6%20Weboldal%3A%20%E2%80%A6

**Röviden:** A PHP Out-of-Memory hiba akkor keletkezik, ha egy szkript több memóriát akar lefoglalni, mint amennyit a `memory_limit` beállítás megenged (alapértelmezés: 128 MB kérésenként). A PHP ilyenkor végzetes hibával megszakítja a kérést, és rendet tesz. Éppen ez a megszakítási és takarítási út volt hibás a CVE-2026-109618-nál, a két PHP2Shell-rés egyikénél. A PHP 8.5.12, 8.4.27, 8.3.36 és 8.2.35 óta a `memory_limit` puha határ, amelyet a `memory_hard_limit_percent` kemény határ egészít ki.

## Mit jelent az „Allowed memory size exhausted”?

Az ismert hibaüzenet értelemszerűen így szól: „Allowed memory size of 134217728 bytes exhausted (tried to allocate …)”. Az első szám a beállított korlát bájtban, itt 128 MB. Egy szkript tehát megpróbált ezen a határon túl memóriát lefoglalni, például egy nagy fájl betöltésekor, egy hatalmas adatbázis-lekérdezésnél vagy egy végtelen ciklus miatt.

A döntéshozók számára fontos: a határ PHP-folyamatonként és kérésenként érvényes, nem az egész szerverre. Megvédi a szervert attól, hogy egyetlen hibás szkript az összes memóriát felhasználja. Az összterhelés csak az egyidejűleg futó workerek számából adódik. 20 PHP-FPM-workernél, egyenként 256 MB határral ez számítás szerint több mint 5 GB.

## Hogyan számolja a PHP a memóriát

A PHP a kérések memóriáját saját memóriakezelőn, a Zend Memory Manageren keresztül kezeli. Nagyobb blokkokat kér az operációs rendszertől, és belsőleg osztja szét őket a változók, tömbök és objektumok között. A PHP a `memory_limit`-et ezzel a lefoglalt értékkel szemben ellenőrzi. Az a memória, amelyet egy bővítmény közvetlenül az operációs rendszertől kér, a kézikönyv szerint nem jelenik meg ebben a számításban.

Az értékeket a kódban láthatóvá teheti:

```php
<?php
echo memory_get_usage(), PHP_EOL;       // a szkript által jelenleg lefoglalt memória
echo memory_get_usage(true), PHP_EOL;   // a memóriakezelő által lefoglalt; a memory_limit ezt ellenőrzi
$liste = range(1, 200000);
echo memory_get_peak_usage(), PHP_EOL;  // az eddigi csúcsérték
unset($liste);
memory_reset_peak_usage();              // csúcsérték visszaállítása, a PHP 8.2-től
```

Hogyan szabadítja fel ismét a memóriát a referenciaszámlálás és a szemétgyűjtés, azt a [Memóriakezelés a PHP-ban](https://phpsos.de/hu/php/speicherverwaltung/) oldal magyarázza.

## Mi történik belül Out-of-Memory esetén

Egyszerűsítve a memória miatti megszakítás ezekben a lépésekben zajlik:

1. A szkript memóriát kér, például egy új tömbelemhez vagy kéradatok beolvasásakor.
2. A memóriakezelő ellenőrzi, hogy a kérés túllépi-e a határt.
3. Ha igen, a PHP végzetes hibát vált ki, és azonnal elhagyja a folyamatban lévő feldolgozást, akár egy félig elvégzett feladat közepén is.
4. A regisztrált shutdown-függvények még lefutnak; sok alkalmazás ezekkel naplózza a hibát.
5. A végén a PHP rendet tesz a kérésnél, és felszabadítja a memóriáját. A worker ezután a következő kérésre készen áll.

A kényes pont az 5. lépés. A takarításnak olyan adatszerkezetekkel is meg kell birkóznia, amelyek a megszakításkor még csak félig voltak létrehozva. A PHP-projekt biztonsági irányelve szerint egy szokásos memória miatti megszakítás nem biztonsági rés, amíg a limit elutasítja a kérést, és csak az aktuális kérés ér véget. A CVE-2026-109618-nál éppen ez a feltevés sérült: a php.net szerint az Out-of-Memory-állapot megszakíthatta a PHP-t, miközben a belső kéradatok csak részben voltak inicializálva, és a takarítás az érvénytelen adatokat érvényesként kezelte. A kihasználás részleteit nem tesszük közzé; a rés besorolása a [CVE-2026-109618](https://phpsos.de/hu/php2shell/cve-2026-109618/) oldalon található.

## Az új puha és kemény memóriahatár

A 2026. október 21-i biztonsági kiadásokkal a PHP-projekt megváltoztatta a viselkedést. A kézikönyv szerint a `memory_limit` azóta puha határ: egy kérés, amely túllépi, a legtöbb esetben még befejezhető, mielőtt a végzetes hiba következik. Egy külön kemény határ korlátozza, meddig mehet ez el.

| Direktíva | Alapérték | Módosítható | Jelentés |
|---|---|---|---|
| `memory_limit` | 128M | INI_ALL | memóriahatár kérésenként, `-1` = nincs határ |
| `memory_hard_limit_percent` | nincs beállítva | INI_ALL | kemény határ a `memory_limit` százalékában, új a 8.5.12, 8.4.27, 8.3.36, 8.2.35 óta |
| `post_max_size` | 8M | INI_PERDIR | a POST-adatok maximális mérete |
| `upload_max_filesize` | 2M | INI_PERDIR | egy feltöltött fájl maximális mérete |

Egy példa a kézikönyvből: `memory_limit=128M` és `memory_hard_limit_percent=150` esetén a kemény határ 192 MB. A kézikönyv a direktívát egyben felismerési jegyként is megnevezi: ha egy PHP-verzió nem ismeri, érinti a CVE-2026-109618 és a CVE-2026-109619. Gyors teszt minden telepített PHP-verzióra:

```bash
php -r 'var_dump(ini_get("memory_hard_limit_percent"));'
# a bool(false) azt jelenti: ismeretlen direktíva
```

A backportot tartalmazó disztribúciós csomagoknál a csomag changelogja marad a mérvadó bizonyíték, ahogyan a [PHP-verzió és javítási állapot helyes ellenőrzése](https://phpsos.de/hu/php2shell/php-version-pruefen/) oldalon le van írva. Ellenőrizze emellett külön a PHP-FPM binárist is, mert más verziójú lehet, mint a parancssor.

## Memóriahatárok és PHP2Shell: amire most az adminisztrátoroknak figyelniük kell

A php.net CVE-2026-109618-ra vonatkozó átmeneti intézkedései szinte mind a memória és a kérésméretek körül forognak. Csökkentik a kockázatot, de nem helyettesítik a frissítést:

```ini
; FPM-pool, pl. /etc/php/8.3/fpm/pool.d/www.conf
php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 8M        ; 32M, ha feltöltések szükségesek
php_admin_value[upload_max_filesize] = 6M  ; a post_max_size alatt tartandó
```

Három pont döntő. Először, egyetlen alkalmazás, könyvtár vagy másik pool sem állíthat be ismét véges határt; a php.net kifejezetten ezt az ellenőrzést követeli. Másodszor, a `memory_limit=-1` értékű szolgáltatásnak kívülről, konténeren vagy cgroupon keresztül kell határt kapnia, a php.net szerint lehetőleg úgy, hogy csak az érintett worker álljon le. Az `RLIMIT_AS` és az `RLIMIT_DATA` a php.net szerint alkalmatlan. Harmadszor, a php.net korlátokat ajánl a webszerveren vagy a proxyn a kérés méretére, a mezők számára, a multipart-részekre, a fejlécekre és a beágyazási mélységre.

> **Fontos:**
> A kívülről érkező memóriahatár nélküli `memory_limit=-1` nagy terhelésnél teljesen megbéníthat egy szervert. Az átmeneti intézkedéseket csak csomagként, és csak a frissítésig alkalmazza.

Hogyan állíthatja be a határt systemd-vel, azt a [Memóriahatárok systemd-vel és cgroupokkal](https://phpsos.de/hu/blog/speichergrenzen-systemd-cgroups/) cikk mutatja; a mindennapi tartós megoldást a [A memory_limit helyes beállítása](https://phpsos.de/hu/blog/memory-limit-richtig-setzen/) írja le.

## Hogyan segít konkrétan a PHP SOS?

A [PHP-javítási szolgáltatáson](https://phpsos.de/hu/leistungen/php-patch-service/) keresztül így járunk el:

- **Az állomány ellenőrzése:** Felmérjük a szerveren lévő minden PHP-verziót, CLI, FPM és Apache-modul szerint külön, és teszteljük, hogy a javított verzió fut-e.
- **A memóriahatárok rendezése:** Megvizsgáljuk, hol állítják be mindenütt a `memory_limit`-et, és úgy alakítjuk ki a pool- és rendszerhatárokat, hogy illeszkedjenek egymáshoz.
- **Az átmenet biztosítása:** Ahol a frissítést még akadály gátolja, a php.net intézkedéseit teljes körűen és felülírás ellen zárva alkalmazzuk.
- **Igazolás szolgáltatása:** A verziókat, a csomagállapotokat és a konfigurációt az beavatkozás előtt és után írásban megkapja.


## Gyakori kérdések

**Mit jelent az „Allowed memory size exhausted” üzenet?**  
Egy szkript több memóriát akart lefoglalni, mint amennyit a memory_limit megenged. A PHP ilyenkor végzetes hibával megszakítja a folyamatban lévő kérést. A többi kérés és maga a szerver tovább fut.

**Az egész szerverre érvényes a memory_limit?**  
Nem, a határ PHP-folyamatonként és kérésenként érvényes. Ha 20 FPM-worker fut egyenként 256 MB határral, együtt elméletileg több mint 5 GB-ot foglalhatnak le. Az összesített határt ezért a poolmérettel, a systemd-vel vagy konténerrel kell beállítani.

**Mi a memory_hard_limit_percent?**  
Egy új direktíva, amely a PHP 8.5.12, 8.4.27, 8.3.36 és 8.2.35 verzióval jelent meg. Kemény határt állít a memory_limit százalékában, amelyet soha nem lehet túllépni. A memory_limit azóta maga is puha határ.

**Véd a memory_limit=-1 a PHP2Shell ellen?**  
Csak részben. A php.net a beállítást a CVE-2026-109618 elleni átmeneti intézkedésként nevezi meg, kifejezetten teljes védelem nélkül. Feltétlenül szükséges hozzá kívülről érkező memóriahatár, és a frissítés továbbra is kötelező.

## Források

- [PHP-kézikönyv: Core-beállítások (memory_limit, memory_hard_limit_percent)](https://www.php.net/manual/en/ini.core.php)
- [PHP-kézikönyv: memory_get_usage()](https://www.php.net/manual/en/function.memory-get-usage.php)
- [php.net: Biztonsági közlemények, 2026. 10. 21.](https://www.php.net/)
