Zadejte hledaný výraz...

Manualna sprava pamete v non-GC jazykoch

glengoolie
verified
rating uzivatele
19. 11. 2022 11:16:41
Robim s Go ktore ma GC a predtym PHP a JS ktore GC neriesia. Chcel by som skusit Zig ale stale nejako nechapem tu manualnu spravu pamete(celkovo, nie v Zigu). Moze mi to niekto vysvetlit?
Konkretne teda niekedy vidim ze sa vytvoria premenne normalne a inokedy sa pre ne alokuje pamet. Chapem to spravne, ze ked sa nepouziva alokator tak tieto premenne beru prealokovane miesto v binarke po buildnuti? To mi moc logiku nedava ale inak ma nic nenapada. Taktiez, ak ukoncim funkciu tak musim riesit alokaciu lokalnych premennych alebo iba takych co pustam z funkcie von?
Pride mi totiz divne, ze ak mam funkciu kde mam 20 premennych tak pre kazdu musim manualne alokovat pamet a potom este manualne to vsetko uvolnit. Myslim ze rust to ma osetrene bez GC ale ked clovek vyjde z funkcie sa ta pamet uvolnuje prave kvoli tomu ich borrow checkeru, kedy ak nejde ownership mimo fc tak sa moze pamet uvolnit(aspon myslim ze to tak je).
Ako by k tomu mal pristupovat niekto kto s manualnou spravou proste nikdy nerobil?
19. 11. 2022 11:16:41
https://webtrh.cz/diskuse/manualna-sprava-pamete-v-non-gc-jazykoch#reply1509611
TomasX
verified
rating uzivatele
(4 hodnocení)
19. 11. 2022 13:02:33
dej od toho ruce pryč, zig je hodně low level jazyk, je velice obtížný, vzhledem k tomu jaký tady máš dotazy, dá ti hodně práce se v tom naučit.
PHP i JS mají GC a řeší ho, mají klasický sweep and mark.
V zigu musíš rozlišovat proměnné alokované na stack (to jsou ty, o kterých mluvíš jako místo v binárce, což je nepřesné) a alokované na heapu. Stack je malý, má pár kb, heapa je prakticky neomezená a pro alokaci v ní musíš používat nějaký alokátor, v zigu máš dostupných několik alokátorů v std https://github.com/ziglang/zig/tree/master/lib/std/heap, případně můžeš použít jiný.
Ano, při manuální alokaci musíš hlídat, kdy proměnou naplníš, před tím musí být pro ní paměť předalokovaná, musíš zvětšit alokaci, když tam chceš uložit více dat než s jakými jsi počítal, stejně tak musíš proměnnou dealokovat, když jí už nepotřebuješ, abys uvolnil paměť, v opačným případě ti vznikají memory leaky a můžeš takhle klidně vyčerpat veškerou paměť na systému velice snadno. při manuální alokaci také musíš myslet na fragmentaci pamětí, musíš zohledňovat velikost alokované paměti a hlavně správě ošetřovat stav, kdy na systému už není paměť. GC jazyk často při nedostatku paměti program zpomalí a jde důrazněji vyčistit nepoužívanou paměti, tady si to musíš řešit sám. Nastávají ti třeba situace, kdy někdy musíš dopředu si alokovat proměnné třeba na ukončení programu nebo chybové hlášky, abys při nedostatku paměti byl schopný se řádně ukončit, zalogovat a zobrazit chybu, i tohle jsou nové problém, které jsi s GC jazyky nemusel řešit.
Když jsem začínal programovat, měl jsem k ruce poznámkový blok, tam jsem si zapisoval do tabulky co která funkce alokuje, která jiná to dealokuje a kde se daná proměnná používá, abych na nějakou nezapomněl. Musíš mít prostě o tom programu a funkcích velice detailní přehled, je těžké v tom neztratit orientaci, zejména, když program má stovky funkcí, běží nonstop a má zpracovávat data.
Ano, rust to má přes vlastnictví proměnných, to je sice navenek skvělá, ale při programování na to musíš myslet, musíš řešit půjčování proměnných jiným funkcím, v jednu dobu může být proměnná pujčená jen jedné funkci, takže musíš často operace dělat postupně nebo data v paměti kopírovat, není to lék, ale funguje to velice dobře, jakmile se to naučíš, opět, není to na pár dní, ale musíš změnit uvažování.
Proč o tom uvažuješ? Rád tohle téma školím, ale spíše pro to, aby programátoři pochopili jak funguje správa paměti, jak je GC užitečné a co vlastně dělá, ne kvůli tomu, aby začali si manuálně spravovat paměti, to je dnes na ústupu, protože v tom i ti nejlepší dělají spousty chyby. Riziko memory overflow a z toho plynoucí zranitelnosti dělají asi 60 % všech zranitelností v programech, to je sakra hodně. Je ale dobré to znát, nikoliv používat, od toho bych odrazoval :).
19. 11. 2022 13:02:33
https://webtrh.cz/diskuse/manualna-sprava-pamete-v-non-gc-jazykoch#reply1509610
glengoolie
verified
rating uzivatele
19. 11. 2022 13:46:55
viem co je stack aj heap, i ked to samozrejme neriesim pri kodeni kvoli gc. fragmentacia pamete je zuajimava tema, to urcite. ale to ma momentalne nemusi zuajimat.
budem buduci rok riesit pracu s videom(transkodovanie ziveho vysielania, kde volat ffmpeg externe skratka nestaci, to je dobre tak akurat na ulohy v pozadi) takze preto ma to zuajima + som uz nejaky cas rozmyslal nad niecim viac low-level(hlavne ked je k dispozicii take velke mnozstvo C kniznic na hranie sa a teda vela zaujimavych moznosti) akurat som nemal ziaden use-case + rozmyslam napsiat chat server v niecom vykonnejsom. Go je super ale ma problem ze jeho networking je robeny na "batteries included" pristup kde trpi vykon vo velmi specificikych pripadoch kedy server obsluhuje konstatne spojenia a to prave chat server presne je(podobne ako smtp server). tak ze na skusku je to idealny projekt. a preco konkretne zig? pretoze rust ma najotrasnejsiu syntax aku som kedy videl a trpi rovnakym problemom ako odin, ktory este nema poriesene sietovanie a konkurenciu/paralelizmus - na windows si vyzaduje stiahnutie 6 giga microsoft sraciek. zig, podobne ako go, nic take nepotrebuje. takze pre pragmaticky ptistup a tiez verim, ze zig bude jeden z tych jazykov ktore sa prerazia do popredia, na rozdiel od rustu napriklad, takze je to taka investicia do buducnosti...i ked nekodim uz pre peniaze.
19. 11. 2022 13:46:55
https://webtrh.cz/diskuse/manualna-sprava-pamete-v-non-gc-jazykoch#reply1509609
TomasX
verified
rating uzivatele
(4 hodnocení)
19. 11. 2022 22:10:11
zrovna stack i heap se řeší s GC, resp. se řeší, co se nechá na heapě a co naopak na stacku kvůli rychlosti. Na linuxu si můžeš zavolat "cat /proc/buddyinfo" a podívat se kolik jak velkých bloků je k dispozici (na windows tady zase je vmmap od sysinternals), občas se stane, že proces spadne na Out of memory a přitom na systému je volná paměť, ale jen v malých nesouvislých blocích a proces si chtěl alokovat velký blok najednou. Na linuxu i windowsu má pak alokace velkého počtu malých bloků obrovskou režiji, tak se používá třeba na linuxu transparent huge pages, kdy si proces pro sebe může vzít i gigabajtový blok najednou a netříštit svoji paměti po 4kb blocích.
Dnes se masivně přepisují všechny ty parsery na uživatelské vstupy na GC jazyky kvůli bezpečnosti, ono se totiž ukazuje, že parsovat něco tak dynamického jako video a ještě k tomu bezpečně je nadlidský úkon. Manuální alokace paměti a paralelismus dohromady je doslova nejtěžší programátorská disciplína, tam selhávají i ti nejlepší.
V go je napsaný třeba nats.io a tam jsme zvládli i 500k spojení na jediném serveru stabilně v produkci, v testech jsem končili na 2M spojení na jediný server, tady to v CZ používá jedna z bank. Problém je jen paměť, na 2M spojení na go s nats režiji asi 40GB RAM a to jen na ty spojení.
Každá alokace pamětí je strašně drahá, jedná se o syscall, to znamená dvakrát context switch a pokud jsou aplikované nejnovější záplaty na rodinu zranitelností spectre (retbleed, retpoline atd.) znamená to i smazání L2/L3 cache, což je strašně drahé. Nezbavuj se GC, je na alokace velice dobře optimalizované, nauč se spíše ho využít ke svému účelu, používej optimalizace v kódu a zůstane ti výhoda GC, nejčastěji se předalokovávají různá byte array a ty se znovu a znovu používají na další a další vstup. Stejně tak paralelismus, vykašli se na to a jdi raději cestou konkurence, např. spustit na každém cpu jádru jednu single thread aplikaci a přímo jí přiřadit tcp socket ze sítě, kernel si to pak bude balancovat sám a vyhneš se zámkům, synchronizacím a dalším drahým operacím.
Jinak ffmpeg nemusíš volat externě, můžeš z něho použít libavformat, libavcodec a další z tvé aplikace přímo.
Samozřejmě, když se chceš učit, uč se co se ti líbí, volba je na tobě. Když něčemu nebudeš rozumět, klidně se zeptej, třeba ti někdo poradí, ale měj konkrétní otázky a ne otevřené. Vysvětlit totiž fungování manuální alokace paměti neumím v pár větách, přečti si dokumentaci https://ziglang.org/documentation/0.10.0/#toc-Memory a https://ziglang.org/documentation/0.10.0/#Choosing-an-Allocator a zeptej se, pokud něčemu nerozumíš.
19. 11. 2022 22:10:11
https://webtrh.cz/diskuse/manualna-sprava-pamete-v-non-gc-jazykoch#reply1509608
glengoolie
verified
rating uzivatele
20. 11. 2022 12:40:02
Celkom zaujimave velkosti binariek Hello world:
Zig 799 kB
Odin 347 kB
Rust 154 kB
Go 1905 kB
Go je jasne, to ma runtime, ale Zig som cakal lepsi vysledok.
Rozmyslam ze mozno skusim ten hnusny skaredy rust na ten chat server(ono to nebude plnohodnotny server ale iba read server s kvdb ktory len pouziva pub-sub brokera v pameti na fan-outovanie sprav, nic komplikovane, akurat ze to ma konstante spojenia), ked tam netreba riesit tu pamet, len sa naucit pracu s tym vlastnictvom. A to zive video sa mi najskor aj tak nebude chciet riesit tak to dam niekomu nakodit potom :)
20. 11. 2022 12:40:02
https://webtrh.cz/diskuse/manualna-sprava-pamete-v-non-gc-jazykoch#reply1509607
Pro odpověď se přihlašte.
Přihlásit