# memory_limit ja Out-of-Memory: mis toimub sees

> PHP Out of Memory arusaadavalt: kuidas memory_limit loeb, mis katkestamisel sisemiselt toimub ja mida see tähendab CVE-2026-109618 puhul.

Allikas: https://phpsos.de/et/php/out-of-memory/  
Seis: 25.10.2026  
Pakkuja: PHP SOS, PHP hädaabi ja serveri turvalisus. Kohene abi WhatsAppis: https://wa.me/491736494914?text=Tere%2C%20PHP%20SOS%2C%20vajame%20abi%20oma%20PHP-serveriga.%20Ettev%C3%B5te%3A%20%E2%80%A6%20Veebisait%3A%20%E2%80%A6

**Lühidalt:** PHP Out-of-Memory viga tekib siis, kui skript tahab taotleda rohkem mälu, kui säte `memory_limit` lubab (vaikimisi: 128 MB päringu kohta). PHP katkestab päringu siis fataalse veaga ja koristab. Just see katkestamis- ja koristustee oli veaga CVE-2026-109618 puhul, mis on üks kahest PHP2Shelli turvaaugust. Alates versioonidest PHP 8.5.12, 8.4.27, 8.3.36 ja 8.2.35 on `memory_limit` pehme piir, mida täiendab kõva piir `memory_hard_limit_percent`.

## Mida tähendab „Allowed memory size exhausted“?

Tuntud veateade kõlab mõtte poolest nii: „Allowed memory size of 134217728 bytes exhausted (tried to allocate …)“. Esimene arv on seatud piir baitides, siin 128 MB. Skript on seega püüdnud hõivata mälu üle selle piiri, näiteks suure faili laadimisel, hiiglasliku andmebaasipäringu korral või lõputu tsükliga.

Otsustajale oluline: piir kehtib PHP protsessi ja päringu kohta, mitte kogu serverile. See kaitseb serverit selle eest, et üksik vigane skript kogu mälu ära kasutaks. Kogukoormus tuleneb alles samal ajal töötavate workerite arvust. 20 PHP-FPM workeri korral, igaühel 256 MB piir, on see arvutuslikult üle 5 GB.

## Kuidas PHP mälu loeb

PHP haldab päringute mälu oma mäluhalduriga, Zend Memory Manageriga. See toob operatsioonisüsteemilt suuremaid plokke ja jagab neid seespidiselt muutujatele, massiividele ja objektidele. Selle reserveeritud väärtuse vastu kontrollib PHP `memory_limit`. Mälu, mida laiendus taotleb otse operatsioonisüsteemilt, selles loendis käsiraamatu järgi ei esine.

Väärtusi saab koodis nähtavaks teha:

```php
<?php
echo memory_get_usage(), PHP_EOL;       // skripti praegu hõivatud mälu
echo memory_get_usage(true), PHP_EOL;   // mäluhalduri reserveeritud; selle vastu kontrollib memory_limit
$liste = range(1, 200000);
echo memory_get_peak_usage(), PHP_EOL;  // seni suurim väärtus
unset($liste);
memory_reset_peak_usage();              // tipuväärtuse lähtestamine, alates PHP 8.2-st
```

Kuidas viidete loendus ja Garbage Collection mälu uuesti vabastavad, selgitab leht [Mäluhaldus PHP-s](https://phpsos.de/et/php/speicherverwaltung/).

## Mis Out-of-Memory korral sees toimub

Lihtsustatult kulgeb mälukatkestus järgmiste sammudega:

1. Skript taotleb mälu, näiteks uue massiivielemendi jaoks või päringuandmete sisselugemisel.
2. Mäluhaldur kontrollib, kas taotlus ületab piiri.
3. Kui jah, annab PHP fataalse vea ja lahkub käimasolevast töötlusest kohe, ka pooleli oleva ülesande keskel.
4. Registreeritud shutdown-funktsioonid veel käivituvad; paljud rakendused logivad nende abil vea.
5. Lõpuks koristab PHP päringu ja vabastab selle mälu. Worker on seejärel järgmiseks päringuks valmis.

Delikaatne koht on samm 5. Koristamine peab hakkama saama andmestruktuuridega, mis olid katkestamise hetkel alles pooleldi loodud. Tavaline mälukatkestus ei ole PHP projekti turvapoliitika järgi turvaauk, kui piir lükkab taotluse tagasi ja lõpeb ainult praegune päring. CVE-2026-109618 puhul oli just see eeldus rikutud: php.net andmetel võis Out-of-Memory seisund PHP töö katkestada ajal, mil sisemised päringuandmed olid alles osaliselt lähtestatud, ja koristamine käsitles kehtetuid andmeid siis kehtivatena. Ekspluateerimise üksikasju me ei avalda; turvaauku käsitleb [CVE-2026-109618](https://phpsos.de/et/php2shell/cve-2026-109618/).

## Uus pehme ja kõva mälupiir

21.10.2026 turvaväljaannetega muutis PHP projekt käitumist. Käsiraamatu järgi on `memory_limit` sestsaadik pehme piir: taotluse, mis seda ületab, tohib enamasti veel lõpule viia, enne kui järgneb fataalne viga. Eraldi kõva piir piirab, kui kaugele see minna tohib.

| Direktiiv | Vaikeväärtus | Muudetav | Tähendus |
|---|---|---|---|
| `memory_limit` | 128M | INI_ALL | mälupiir päringu kohta, `-1` = piiri pole |
| `memory_hard_limit_percent` | seadmata | INI_ALL | kõva piir `memory_limit`'i protsendina, uus alates 8.5.12, 8.4.27, 8.3.36, 8.2.35 |
| `post_max_size` | 8M | INI_PERDIR | POST-andmete maksimaalne suurus |
| `upload_max_filesize` | 2M | INI_PERDIR | üleslaaditud faili maksimaalne suurus |

Näide käsiraamatust: kui `memory_limit=128M` ja `memory_hard_limit_percent=150`, on kõva piir 192 MB. Käsiraamat nimetab direktiivi samas ka tunnuseks: kui PHP versioon seda ei tunne, mõjutavad seda CVE-2026-109618 ja CVE-2026-109619. Kiire test iga paigaldatud PHP versiooni jaoks:

```bash
php -r 'var_dump(ini_get("memory_hard_limit_percent"));'
# bool(false) tähendab: direktiiv on tundmatu
```

Backportiga distributsioonipakettide puhul jääb paketi muudatuslogi otsustavaks tõendiks, nagu on kirjeldatud lehel [PHP versiooni ja paigaseisu õige kontrollimine](https://phpsos.de/et/php2shell/php-version-pruefen/). Kontrollige lisaks PHP-FPM binaari eraldi, sest see võib olla teine versioon kui käsurea oma.

## Mälupiirid ja PHP2Shell: mida adminnid nüüd silmas peavad

php.net ajutised meetmed CVE-2026-109618 vastu keerlevad peaaegu kõik mälu ja päringumahtude ümber. Need vähendavad riski, kuid ei asenda uuendust:

```ini
; FPM-pool, nt /etc/php/8.3/fpm/pool.d/www.conf
php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 8M        ; 32M, kui üleslaadimisi on vaja
php_admin_value[upload_max_filesize] = 6M  ; hoida post_max_size'ist väiksemana
```

Kolm punkti on seejuures otsustavad. Esiteks ei tohi ükski rakendus, kataloog ega muu pool uuesti lõplikku piiri seada; php.net nõuab selgesõnaliselt seda kontrolli. Teiseks vajab teenus, kus `memory_limit=-1`, piiri väljastpoolt, konteineri või cgroupi kaudu, php.net järgi kõige parem selliselt, et lõpetatakse ainult mõjutatud worker. `RLIMIT_AS` ja `RLIMIT_DATA` on php.net järgi sobimatud. Kolmandaks soovitab php.net piiranguid veebiserveris või puhverserveris päringu suuruse, väljade arvu, multipart-osade, päiste ja pesastussügavuse jaoks.

> **Oluline:**
> `memory_limit=-1` ilma väljastpoolt seatud mälupiirita võib serveri suure koormuse korral täielikult halvata. Seadke ajutised meetmed ainult paketina ja ainult uuenduseni.

Kuidas piiri systemd-ga seada, on lehel [Mälupiirangud systemd ja cgroupidega](https://phpsos.de/et/blog/speichergrenzen-systemd-cgroups/); püsilahendust igapäevaks kirjeldab [memory_limit õige seadmine](https://phpsos.de/et/blog/memory-limit-richtig-setzen/).

## Kuidas PHP SOS konkreetselt aitab?

[PHP paikamisteenuse](https://phpsos.de/et/leistungen/php-patch-service/) kaudu tegutseme nii:

- **Olemasoleva kontroll:** Kogume serveris kõik PHP versioonid, eraldi CLI, FPM ja Apache'i mooduli kaupa, ning testime, kas parandatud versioon töötab.
- **Mälupiiride korrastamine:** Kontrollime, kus kõikjal `memory_limit` seatakse, ja seame pooli- ja süsteemipiirid nii, et need sobivad kokku.
- **Üleminekuaja kindlustamine:** Kus uuendus on veel blokeeritud, seame php.net meetmed täielikult ja ülekirjutamise vastu lukustatult.
- **Tõendi esitamine:** Saate versioonid, paketiseisud ja seadistuse enne ja pärast sekkumist kirjalikult.


## Korduma kippuvad küsimused

**Mida tähendab teade „Allowed memory size exhausted“?**  
Skript tahtis taotleda rohkem mälu, kui memory_limit lubab. PHP katkestab käimasoleva päringu siis fataalse veaga. Teised päringud ja server ise töötavad edasi.

**Kas memory_limit kehtib kogu serverile?**  
Ei, piir kehtib PHP protsessi ja päringu kohta. Kui töötab 20 FPM workerit, igaühel 256 MB piir, võivad nad koos teoreetiliselt hõivata üle 5 GB. Üldpiir tuleb seetõttu seada pooli suuruse, systemd või konteineri kaudu.

**Mis on memory_hard_limit_percent?**  
Uus direktiiv, mis tuli versioonidega PHP 8.5.12, 8.4.27, 8.3.36 ja 8.2.35. See seab kõva piiri memory_limit'i protsendina, mida ei ületata kunagi. memory_limit ise on sestsaadik pehme piir.

**Kas memory_limit=-1 kaitseb PHP2Shelli eest?**  
Ainult osaliselt. php.net nimetab seadet ajutise meetmena CVE-2026-109618 vastu, selgesõnaliselt ilma täieliku kaitseta. See vajab tingimata väljastpoolt seatud mälupiiri ja uuendus jääb kohustuslikuks.

## Allikad

- [PHP käsiraamat: tuumasätted (memory_limit, memory_hard_limit_percent)](https://www.php.net/manual/en/ini.core.php)
- [PHP käsiraamat: memory_get_usage()](https://www.php.net/manual/en/function.memory-get-usage.php)
- [php.net: turvateated 21.10.2026](https://www.php.net/)
