... proto většina mých démonu napsaných C++ dědí třídu ServiceApp, která sama umí zpracovat příkazy "start","stop","restart", "run" (foreground), takže aplikace je vlastně init scriptem. Navíc zvládne i spoustu dalších uživatelských příkazů, umí předat démonovi i další parametry na příkazové řádce a pokud něco démon vyplivne na stderr, tak se to přenese volajícímu do konzole (a nikoliv na stderr procesu init).
Démoni padaly, padají a padat budou, protože je nevytvářejí kyborgové, nýbrž lidé z masa a kostí a ti dělají chyby. Normální stav je že v OS existuje něco jako správce daemonů, který je spouští, zastavuje, atd. a sleduje jejich stav a pokud si to uživatel přeje, tak je v případě pádu i znovu nahodí. Linux v tomto normální není.
No pozor, odlište pád a výjimku. Jelikož jsem C++ programátor, tak pro mne je výjimka ošetřitelný stav, zatímco pád nikoliv. A pokud démon padá, tak první opravou je na místě pádu udělat test a vyhodit výjimku.
Ano Linux normální není, to je pravda. Samozřejmě, že pro Linux je ta třída implementovaná tak, že démona pustí jako forknutý child, a když ten child skončí, tak ho naforkuje znova. Ale není to žádná výhra, protože takhle může forkovat do nekonečna.
>> Normální stav je že v OS existuje něco jako správce daemonů, který je spouští, zastavuje, atd.
Jasně - třeba ve Windows. Tam je to vymyšleno suprově - zatímco když mám nějaký problém s daemonem pod Unixy, tak si ho prostě spustím normálně ručně v terminálu na popředí, zapnu si volby jaké chci a debuguju jako každý jiný proces, na Windows udělám co? Nejspíš na to budu zase muset mít nějaký SuperDuperMicrosoftServiceDebugger. Hurá.
Ale jinak hlavně, že je to "normální".
Když začne řádit OOM Killer, tak je snad lepší restartovat celý stroj. Jaký to má význam, pokud OOM Killer zabije démona, který se následně hned znova spustí, aby jej OOM Killer zase zabil?
Na světě je moc lidí, náhodně některé popravíme...
OOM Killer je big fail linuxu. Kéž by konečně byl linux schopen pořešit swap + kvóty na alokovanou paměť. Už asi chápu, proč naši admini raději strkaj každou službu do virtuálu :-)
> Když začne řádit OOM Killer, tak je snad lepší restartovat celý stroj. Jaký to má význam, pokud OOM Killer zabije démona, který se následně hned znova spustí, aby jej OOM Killer zase zabil?
To má smysl v případech kdy ten démon zblbnul tak že naalokoval neobvykle moc paměti.
> Na světě je moc lidí, náhodně některé popravíme...
OOM Killer rozhodně nefunguje náhodně.
> OOM Killer je big fail linuxu. Kéž by konečně byl linux schopen pořešit swap + kvóty na alokovanou paměť. Už asi chápu, proč naši admini raději strkaj každou službu do virtuálu :-)
Cgroups?
"To má smysl v případech kdy ten démon zblbnul tak že naalokoval neobvykle moc paměti"
V tom případě je to v pořádku, protože to je chyba, která musí být opravena. Ale radši bych, kdyby jádro žravým procesům začalo utahovat limity včas, aby démonovi začali lítat vyjimky OutOfMemoryException, než že bude sestřelen. Možná opravdu změnit alokační strategii.
Pro memory leaky je nejlepší právě swap. Ty se tam vesele odloží a pak už nikomu nechybí paměť :-)
Nicméně jsem měl s OOM Killerem už zkušenost a to takovou, kdy mi žravý adobe flashplayer vyžral paměť tak, že mi OOM sestřelil Eclipse i s rozdělanou prací. Možná že eclipse zabíral víc paměti, nevím, ale rozhodně to nebylo dobré řešení.
Třeba hodně pomůže to, že Windows nemá overcommit a autoři aplikací nepoužívají malloc na rezervaci adresového prostoru (fakt blbej nápad). Pak není problém vůbec řešit killování aplikací. Aplikace jednoduše dostane zamítnutý požadavek na další paměť. A jestli se kilne sama, nebo to vyřeší jinak je její problém.
Mimochodem, včera jsem si s tím hrál a na stroji bez swapu jsem vypnul overcommit. Výsledkem bylo, že mi nenaběhne ani Unity, protože si procesy rezervují stovky megabajtů a velice rychle tak vyčerpají volnou paměť, přestože ji nikdy nepoužijí.
No ptáš se nesmyslně, protože pokud není třeba zabíjet procesy kvůli nedostatku paměti, je zbytečný vědět, zda je proces žravý korektně či nekorektně.
Pokud máme v systému procesy, které sežerou většinu paměťi, že ostatní procesy už prakticky nemohou běžet, otázku, zda je to chyba nebo schválně musí zodpovědět člověk... Například nastavením limitů nebo vrácením programu autorovi k opravě.
Řešit to pomocí OOMK je blbost. Jak píšou na těchto stránkách:
¨
http://www.win.tue.nl/~aeb/linux/lk/lk-9.html
"Of course, the very existence of an OOM killer is a bug."
Nejde to, protože autoři aplikací používají malloc pro rezervaci adresového prostoru, což není totéž jako rezervace paměti. Ve Windows se to rozlišuje. Stránky se buď rezervují (RESERVED), nebo commitují (COMMITED). V režimu RESERVED se sice vedou ve stránkovém registru procesu, ale nic v nich není, nelze do nich zapisovat, ani číst, fyzicky neexistují. Jakmile ji aplikace potřebuje, provede na kterékoliv rezervované stránce COMMIT a tím dostane přidělenou paměť. A nebo taky ne, pokud OS nemá kde brát.
Jenže aplikace třeba kolem UNIT po startu zarezervuji stovky megabajtů, které reálně nikdy nepoužijí. Pravděpodobně tedy používají malloc jen pro rezervaci adresového prostoru. Bohužel to operačnímu systému nehlásí, takže ten nemůže tušit, zda zabraná paměť opravdu může být v budoucnu reálně potřebná.
ULimit je fajn, ale neumí nastavovat limit nějak chytře, třeba na základě aktuálního stavu paměti. Třeba bych chtěl, aby limit každé aplikace byl vztažen k aktuálně volné paměti. Třeba pokud si nastavím limit 80%, budu schopen jeden jedním procesem využít celých 80% a dalším procesem 80% ze zbývajících 20%. Ale takovouhle logiku v linuxu nenajdu.
Unity tu nemám, tak to nemůžu zkoušet. Tipuju, že si spíš vyrobí nějaké mmapy s MAP_NORESERVE (obdoba RESERVED ve Windows, ale s automatickým commitem), což se ale u vypnutého overcommitu ignoruje a stránky se stejně commitují.
Btw. pokud vypnete overcommit, je potřeba ještě poladit overcommit_ratio, protože ve výchozím nastavení aplikace mohou alokovat jenom 50 %. (Pokud nastavíte moc, může se spustit OOM killer, když dojde jaderná paměť nebo cache.)
overcommit_ratio určuje počet procent RAM, která může být zabraná při overcommit_memory nastavené na 2 (overcommit_memory nastavené na 0 používá heuristiku, na 1 povoluje neomezený overcommit), tedy total_commit = swap_size + (ram_size * overcommit_ratio / 100) — stále to neznamená, že ta paměť bude při mallocu či mmapu opravdu zabrána jako ve Windows, může v ní být třeba cache nebo file-backed mmap (oboje lze kdykoliv snadno zahodit). Pokud je overcommit_ratio nastavené pod cca 80 (aby zůstalo dost místa na jádro a buffery), k overcommitu (a tedy na OOM killer) nemůže dojít.
No, jádro se o to snaží, když je zapnutá heuristika, ale už ze samotného principu alokace paměti není možné mít něco jako nealokovanou zaručenou rezervaci a nezaručená rezervace je (alespoň v Unixu) totožná se žádnou rezervací, takže je celkem zbytečné něco explicitně rezervovat (autoři Unity se asi chtěli vybodnout na kontroly mallocu).