Portál AbcLinuxu, 20. května 2025 23:46
ndb-serveru
jen prázdný děravý (sparse) soubor, popř. partition, a mkswap
udělat až na straně klienta. U rozdílných architektur či bitovostí je to nutnost.
$a="x"x(1024**4);
zhrouti s Out of memory hlaskou a nic se neswapne.
Nevola se OOM pouze v pripade, ze dochazi fyzicka pamet a nic se z ni neda hodit na swap?OOM killer se spouští skutečně jen v případě, že dochází fyzická paměť a nelze žádnou uvolnit. Ale to je právě typicky případ vyčerpání swapu, protože jsou v paměti neaktivní anonymně mapované stránky, které není kam odložit. Není mi jasné, jak by mohl Perl "používat pouze RAM", pokud by si předem nezamkl příslušné stránky v paměti, aby nemohly být odloženy. A nemyslím si, že si při každé stringové operaci ty stránky zamyká a pak je zase odemyká.
Prozatím co je mi známo, tak když začne docházet paměť, tak OOM killer ukončí podle nějakého algoritmu určitou aplikaci. Mi by se docela líbilo, kdyby ještě předtím…
…skočil do krámu a dokoupil RAMku. A na závěr uvařil kafe.
Takhle by se to líbilo mně.
kde je málo paměti(256 MB RAM + 256 MB Swapu na CF kartě)LOL, taky dobrý.
Prozatím co je mi známo, tak když začne docházet paměť, tak OOM killer ukončí podle nějakého algoritmu určitou aplikaci.On neukončí podle nějakého algoritmu určitou aplikaci, ale snaží se nalézt aplikaci, která najednou sežrala co nejvíc paměti (např. aplikace které se ve smyčce zaseklo alokování paměti a tak bude alokovat do nekonečna – taková aplikace si ani nic jiného než smrt nezaslouží). A ještě takové aplikaci dopřávat více místa? Mně to teda přijde pěkně padlé na hlavu. Jinak kvůli tomu není potřeba vymýšlet znova kolo:
dd if=/dev/zero of=/lokalni/swap/v/souboru.img bs=1M count=100 losetup /dev/loop0 /lokalni/swap/v/souboru.img mkswap /dev/loop0 swapon /dev/loop0A po použití:
swapoff /dev/loop0 losetup -d /dev/loop0 rm /lokalni/swap/v/souboru.imgAkorát mě teda opravdu nenapadá rozumný příklad použití něčeho takového. Něco podobného dělá Windows.
A ještě takové aplikaci dopřávat více místa? Mně to teda přijde pěkně padlé na hlavu.Padlé na hlavu to není. Někdy se stává, že nějaká aplikace potřebuje dočasně opravdu hodně místa, protože se s ní prostě pracuje tak, že má velké paměťové požadavky (stačí se třeba otevřít nějakou webovou stránku, na kterou někdo naházel hromady fotek přímo z 12Mpx foťáku nebo tam narval extrémně prasácký Flash). Standardně by nastalo to, že by se spustil OOM killer a pravděpodobně by sestřelil právě tuto aplikaci (není to ovšem úplně jisté, algoritmus může dojít k jinému soudu). Jenže ještě před spuštěním killera by se jádro snažilo usilovně získat jakoukoli paměť, která je získatelná, což může zabetonovat systém na desítky sekud až minuty. V souvislosti s někdejší interakcí mezi Operou a X serverem (kdy X server kvůli Opeře zběsile alokoval paměť - lze to najít v mém blogu několik let zpátky) jsem ohledně tohoto načerpal docela slušné praktické zkušenosti.
Padlé na hlavu to není. Někdy se stává, že nějaká aplikace potřebuje dočasně opravdu hodně místa, protože se s ní prostě pracuje tak, že má velké paměťové požadavkyPadlé na hlavu to je. Pokud se tak aplikace chová, tak to jen značí to, že je aplikace špatně navrhuntá a pak si nezaslouží nic jiného než přepis a nebo výmaz z disku. V 99% případů jde jakýkoliv algoritmus přepsat tak aby nepotřeboval sežrat veškerou paměť počítače.
Příklad ze včerejška: Potřeboval jsem zprůměrovat přibližně 400 obrázků pomocí ImageMagicku, tak prostě z pohodlnosti jsem napsal: convert *.png -average avg.png
. Dostal jsem se k něčemu podobnému. Všech 400 obrázků o rozlišení 640x480 se načetlo a rozbalilo do paměti a zbobroval jsem na něčem podobném. Ale ani za boha by mě nenapadlo navyšovat dočasně velikost swapu nebo obviňovat autory ImageMagicku z diletantství. Ten diletant jsem byl já, protože správně to mělo být mv 0000001.png avg.png && for a in 0000*.png; do convert avg.png $a -average avg.png;done
. Toť vše co se snažím říct.
stačí se třeba otevřít nějakou webovou stránku, na kterou někdo naházel hromady fotek přímo z 12Mpx foťáku nebo tam narval extrémně prasácký Flash)O webech s 12Mpix fotkami nebo prasáckým flashem si myslím své a takové si IMHO rozšiřování swapu rozhodně nezaslouží.
Jenže ještě před spuštěním killera by se jádro snažilo usilovně získat jakoukoli paměť, která je získatelná, což může zabetonovat systém na desítky sekud až minuty.Pravda. Tady je chyba. Taková aplikace si zaslouží byt zabita ještě mnohem dříve.
Pokud se tak aplikace chová, tak to jen značí to, že je aplikace špatně navrhuntáEclipse a jeho úžasné SWT mi naleakovalo denně 400 MB v X-Serveru.
a pak si nezaslouží nic jiného než přepisJá budu přepisovat Eclipse a X-Server. Jasněéé! Hurá do toho.
a nebo výmaz z disku.Přesně tohle jsem udělal.
Já budu přepisovat Eclipse a X-Server. Jasněéé! Hurá do toho.Pokud to byla chyba X-Serveru, tak místo kvíkání aspoň bug report by vhodný byl. Eclipse neznám, takže se k němu vyjadřovat nebudu. Ale určit která aplikace si to zaslouží a která ne není tak jednoduché jak tady popisuju. SIGSTOP a nech si uživatel rozhodne jestli si to zaslouží nebo ne.
V 99% případů jde jakýkoliv algoritmus přepsat tak aby nepotřeboval sežrat veškerou paměť počítače.
To je ovšem klasické dilema. Rychlost/paměť. I pro ten tvůj případ by mělo být rychlejší těch 400 fotek natlačit do paměti a tam je naráz zpracovat, než 400x ukládat nějaký dočasný soubor a 400x pouštět nový proces.
určitě by se dali spočítat na prstech dvou rukK 1023 se to snad nepřibližuje.
Jestli se jich všech čtyři-sta natlačí do paměti a pak zpracuje a nebo se načítají postupně jedna za druhou a přidávají se postupně k průměru je úplně jedno.Tak to samozřejmě není. Jestliže se opravdu jedná o průměr, pak se při osmi bitech na barevný kanál a postupném přidávání nemusíš vůbec obtěžovat s importem prvních cca 390 fotek.
Přemýšlel jsem ještě nad jiným problémem. Aby toto "iterováni" fungovalo, musel by se mezivýsledek ukládat do formátu s mnohem vyšší bitovou bloubkou na kanál než požadovaný výstup. A to k vůli zaokrouhlovací chybě.Mám zkompilovaný ImageMagick se parametrem --enable-hdri, který funguje ve floating-point a dovede zpracovávat až 96-bitové TIFFy. Mezivýsledky ukládám do interního formátu ImageMagicku s koncovkou miff, který většinou stačí jen namapovat. Ale stejně je rozptyl tak veliký, že nějaký kvantizační šum od 8-bitů je jen pakatel.
m_{k+1} = m_k + (x_{k+1} - m_k) / (k+1)
, kde m_k
je průměr prvních k-čísel
Jenže ještě před spuštěním killera by se jádro snažilo usilovně získat jakoukoli paměť, která je získatelná, což může zabetonovat systém na desítky sekud až minuty.Když má člověk vypnutý swap, tak je vzpamatování se systému z nedostatku paměti záležitost pár vteřin.
No, ve chvíli kdy pustím klasickou Cčkovou hračku for(;;) malloc(1024**2); tak se systém paradoxně chová líp bez swapuTo je kod ktery pravdepodobne alokuje dalsi pamet prilis rychle, takze ona faze mezi tim, kdy prakticky dojde pamet, a nez se spusti OOM killer, je prilis kratka (i kdyz je otazka, jakou rychlosti ten kod tu pamet vlastne alokuje - samotny malloc 1 MB by toho moc realne alokovat nemusel, pokud se na ty stranky nepristupuje. Doporucil bych tam pridat jeste smycku, co na kazde 4 kB zapise nejakou hodnotu). U realnych programu, ktere alokuji pamet pomalu a nejak s ni opravdu pracuji, je ten prubeh jiny. Sam na svem pocitaci swap nemam, tak s tim mam par zkusenosti. :–)
samotny malloc 1 MB by toho moc realne alokovat nemusel, pokud se na ty stranky nepristupuje. Doporucil bych tam pridat jeste smycku, co na kazde 4 kB zapise nejakou hodnotuAno, pouhý malloc() u typického systému (výchozí nastavení, tj. s memory overcommittingem) nezpůsobí alokaci paměti, protože příslušné volání brk() jen přidá položky do tabulky stránek. K vlastní alokaci dojde až při přístupu do té paměti.
Note that a swap file must not contain any holes.Ale přiznávám, že překládat pozici na disku pomocí loop zařízení je ještě debilnější než vůbec mu takový soubor přidělovat. (Nemam tolik spojitého volného prostoru na disku)
swaponu
stačí i soubor.
A na ovlivnění OOM killera tu v novýějších jádrech existuje parametr oom_adj
, který ovlivnuje, a oom_scrore
, který ukazuje aktuální stav. Viz dokumentace:
2.12 /proc/<pid>/oom_adj - Adjust the oom-killer score This file can be used to adjust the score used to select which processes shall be killed in an out-of-memory situation. Giving it a high score, increase the likelihood of this process being killed by the oom-killer. Valid values are in the range [-16:15], plus the special value '-17', which defeat the oom-killer altogether. 2.13 /proc/<pid>/oom_score - Display current oom-killer score This file can be used to check what the current score used by the oom-killer is for any given <pid>. Use it together with /proc/<pid>/oom_adj to tune which process will be killed in an out-of-memory situation.Takže není problém OOM killera ukecat pomocí velkého záporného
oom_adj
, případně ho zcela zažehnat hodnouou -17.
JS chce nejspis rict, ze neni pravda, ze kdyz zada, tak potrebuje. S vetsim mnozstvim dostupne pameti by treba mohl bezet rychleji (mezi vysledky si muze napr. cachovat v pameti nebo znovu dopocitat). Proces ale nevi, o kolik si muze rict, aby to nebylo sobecke.To ale v žádném případě není starost nikoho jiného než programátora. To by mělo jako jádro rozhodovat jestli to místo které proces žádá ho opravdu potřebuje? To je především starost programátora, ne? Vím že neznalost a lenost programátorů řeší prostě rychlejším HW(je to levnější), ale ještě aby jejich problémy řešilo i jádro systému? Co by ti programátoři, resp. analytici a softwarový inženýři vůbec ještě dělali kdyby to za ně řešili všichni ostatní? Váleli se na Bahamách?
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.