Může.
V Linuxu se můžete setkat se dvěma různými stavy nedostatku paměti. Na co narazíte, závisí na hodnotě sysctl vm.overcommit_memory
(/proc/sys/vm/overcommit_memory
)
Úvod:
Jádro může provádět to, čemu se říká 'přetížení paměti'. To je, když jádro přiděluje programům více paměti, než je skutečně přítomno v systému. Děje se tak v naději, že programy ve skutečnosti nevyužijí veškerou přidělenou paměť, protože je to docela běžný jev.
overcommit_memory =2
Když overcommit_memory
je nastaven na 2
, jádro neprovádí vůbec žádný overcommit. Místo toho, když je programu přidělena paměť, je zaručen přístup k této paměti. Pokud systém nemá dostatek volné paměti k uspokojení požadavku na alokaci, jádro pouze vrátí selhání požadavku. Je na programu, jak situaci elegantně zvládne. Pokud nezkontroluje, že alokace byla úspěšná, když skutečně selhala, aplikace často narazí na segfault.
V případě segfault byste měli najít takovýto řádek ve výstupu dmesg
:
[1962.987529] myapp[3303]: segfault at 0 ip 00400559 sp 5bc7b1b0 error 6 in myapp[400000+1000]
at 0
znamená, že se aplikace pokusila o přístup k neinicializovanému ukazateli, což může být výsledek neúspěšného volání alokace paměti (ale není to jediný způsob).
overcommit_memory =0 a 1
Když overcommit_memory
je nastaven na 0
nebo 1
, je povoleno overcommit a programy mohou alokovat více paměti, než je skutečně dostupné.
Když však program chce použít paměť, která mu byla přidělena, ale jádro zjistí, že ve skutečnosti nemá dostatek paměti k uspokojení, potřebuje získat část paměti zpět. Nejprve se pokusí provést různé úkoly čištění paměti, např. jako vyprázdnění mezipaměti, ale pokud to nestačí, proces se ukončí. Toto ukončení provádí OOM-Killer. OOM-Killer se podívá na systém, aby zjistil, jaké programy používají jakou paměť, jak dlouho běží, kdo je spouští, a řadu dalších faktorů, aby zjistil, který z nich bude zabit.
Po ukončení procesu se paměť, kterou používal, uvolní a program, který právě způsobil stav nedostatku paměti, má nyní paměť, kterou potřebuje.
I v tomto režimu však mohou být programům stále odepřeny požadavky na přidělení. Když overcommit_memory
je 0
, jádro se snaží co nejlépe odhadnout, kdy by mělo začít odmítat požadavky na alokaci. Když je nastaveno na 1
, Nejsem si jistý, jaké určení používá k určení, kdy má odmítnout požadavek, ale může odmítnout velmi velké požadavky.
Můžete zjistit, zda je zapojen OOM-Killer, když se podíváte na výstup dmesg
a nalezení zpráv jako:
[11686.043641] Out of memory: Kill process 2603 (flasherav) score 761 or sacrifice child
[11686.043647] Killed process 2603 (flasherav) total-vm:1498536kB, anon-rss:721784kB, file-rss:4228kB
Pravdou je, že bez ohledu na to, z jaké strany se na to díváte – zda se váš proces zadrhl kvůli správci paměti systému nebo kvůli něčemu jinému – je to stále brouk. Co se stalo se všemi těmi daty, které jste právě zpracovávali v paměti? Mělo to být uloženo.
Zatímco overcommit_memory=
je nejobecnější způsob konfigurace správy OOM Linuxu, je také nastavitelný podle procesu, jako je:
echo [-+][n] >/proc/$pid/oom_adj
Pomocí -17
ve výše uvedeném vyloučí proces ze správy nedostatku paměti. Pravděpodobně to obecně není skvělý nápad, ale pokud lovíte chyby, mohlo by to být užitečné – zvláště pokud chcete vědět, zda to bylo OOM nebo váš kód. Pozitivní zvýšení čísla zvýší pravděpodobnost, že bude proces ukončen v události OOM, což vám umožní lépe podepřít odolnost vašeho kódu v situacích s nedostatkem paměti a zajistit, abyste v případě potřeby elegantně skončili.
Aktuální nastavení obslužné rutiny OOM můžete zkontrolovat podle procesu, například:
cat /proc/$pid/oom_score
Jinak byste mohli spáchat sebevraždu:
sysctl vm.panic_on_oom=1
sysctl kernel.panic=X
To nastaví počítač na restartování v případě nedostatku paměti. Nastavíte X
výše na počet sekund, po který chcete, aby se počítač zastavil po panice jádra před restartem. Zbláznit se.
A pokud se z nějakého důvodu rozhodnete, že se vám to líbí, udělejte to trvalým:
echo "vm.panic_on_oom=1" >> /etc/sysctl.conf
echo "kernel.panic=X" >> /etc/sysctl.conf