Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: geek 03. 02. 2016, 20:05:35
-
Mám dotaz, na který se mi nepovedlo vygooglit odpověď: Proč je latence GC v Go o tolik menší než v Javě? Při velké haldě (nad řekněme 16GB) se Java zasekává na vteřiny, kdežto Go zamrzne jen na pár milisekund. Cvičně jsem nahrál do paměti celou naši firemní databázi (přes 10 GB) a při práci s vše jede Go hladce, zatímco Java "stops the world". Testováno na Linuxu, Java je od Oraclu, Go verze 1,5.
-
este nedavno (go 1.4.1) to bolo nahovno aj v go. ale teraz v 1.5 to komplet prerobili a je to parada
-
Asi v Javě používáte nevhodný GC. Zkoušel jste G1?
-
Asi v Javě používáte nevhodný GC. Zkoušel jste G1?
presne toto je filozofia java sveta, spravit vela garbage collectorov, v kazdom milion parametrov, potom mat v produkcii zvlast
cloveka co nic ine nerobi nez furt ladi parametere tych garbage collectorov
-
Těžko říct, záleží, jaký typ GC se v té Javě používá. Paralelní mark+sweep (-XX:+UseConcMarkSweepGC), který používá Go, je velmi rychlý, i když není tak efektivní. Máme v Javě několik serverů, které mají haldy v gigabajtech, a žádné záseky tam CMS nejsou, ani když paměť lítá. Můžete zkusit i hodně nový G1 (-XX:+UseG1GC), ten je i soft realtime (-XX:MaxGCPauseMillis=200).
Druhá možnost je, že se to dostane až blízko k OOM. Nevím, jak se v takovém případě chová Go, ale Java se snaží opravdu hodně, aby uvolnila veškerou poslední paměť, kterou může, což při takové haldě opravdu bude trvat dlouho (ale i to lze změnit).
-
Pokud bych dnes programoval GC, asi bych segmentoval hromadu na mikrooddíly se samostatnou správou. Každé spuštění GC by pak defragmentovalo jen jeden oddíl. Sice by se to muselo spouštět častěji, ale zkrátily by se latence.
Třeba podobnou strategii použili i v novém Go.
-
Asi v Javě používáte nevhodný GC. Zkoušel jste G1?
presne toto je filozofia java sveta, spravit vela garbage collectorov, v kazdom milion parametrov, potom mat v produkcii zvlast
cloveka co nic ine nerobi nez furt ladi parametere tych garbage collectorov
To bude tím, že u GC musíte vyvažovat mezi rychlý, konkurentní a efektivní. Tudíž neexistuje univerzální GC, který bude dobře fungovat na jednojádrových strojích s desítkami MiB RAM, na vícejádrových (jednoprocesorových) strojích s pár GiB RAM i na strojích s mnoha procesory a desítkami GiB NUMA RAM. A proto Java dává možnost volby a detailní nastavení. Možná by dnes už stálo za to, aby Java měla jako výchozí CMS, ale komunita kolem Javy je hodně konzervativní k jakýmkoliv změnám výchozího nastavení.
-
Asi v Javě používáte nevhodný GC. Zkoušel jste G1?
presne toto je filozofia java sveta, spravit vela garbage collectorov, v kazdom milion parametrov, potom mat v produkcii zvlast
cloveka co nic ine nerobi nez furt ladi parametere tych garbage collectorov
To bude tím, že u GC musíte vyvažovat mezi rychlý, konkurentní a efektivní. Tudíž neexistuje univerzální GC, který bude dobře fungovat na jednojádrových strojích s desítkami MiB RAM, na vícejádrových (jednoprocesorových) strojích s pár GiB RAM i na strojích s mnoha procesory a desítkami GiB NUMA RAM. A proto Java dává možnost volby a detailní nastavení. Možná by dnes už stálo za to, aby Java měla jako výchozí CMS, ale komunita kolem Javy je hodně konzervativní k jakýmkoliv změnám výchozího nastavení.
jdk 9 by melo mit defaultni G1, jeste se o tom diskutuje.
zatim pouzivam CMS, pri upgrade ze 7 na 8 jsem presel z iCMS na CMS a zatim v pohode. Max full gc bylo po 2 mesicich provozu bez restartu 2s a full gc se provedlo tusim 10x. Heap 6gb, vetsionu vyuzito tak 2 - 3 gb. Oproti iCMS jsem se jeste nikdy nedostal pres 5gb heapu.
-
Asi v Javě používáte nevhodný GC. Zkoušel jste G1?
presne toto je filozofia java sveta, spravit vela garbage collectorov, v kazdom milion parametrov, potom mat v produkcii zvlast
cloveka co nic ine nerobi nez furt ladi parametere tych garbage collectorov
Budu hadat, ze ani ten jeden clovek moc zazraku neudela.
Neznam Vas kontext, ale stalo by za to se podivat, jestli to neni chyba mezi programatorovou klavesnici a zidli. Nevhodne nakladani s pameti zpusobuje presne, co jste popsal. Immutable objekty, zpracovani velkeho mnozstvi dat ve streamu by mohlo pomoct. Misto "patternu" nacti vse, zpracuj vse, zahod vse, kde vse je v radu stovek megabajtu. To se pak gc pekne zapoti.
-
pan mozna spatne guglil :
http://lmgtfy.com/?q=golang+new+gc (http://lmgtfy.com/?q=golang+new+gc)
nic proti jave samozrejme
-
Pretoze golang pouziva mierne upraveny algoritmus, ktory vymyslel jeden z autorov. Ma niekde vycapeny aj dokaz korektnosti, ale o podrobnosti som sa nezaujimal.
-
Nevhodne nakladani s pameti zpusobuje presne, co jste popsal. Immutable objekty, zpracovani velkeho mnozstvi dat ve streamu by mohlo pomoct.
Není naopak naprosto obráceně lepší se těch immutable objektů zbavit? Mít jeden objekt který mění vnitřní stav je přeci pro GC mnohem lepší než pořád vytvářet nové immutable objekty!
-
Pretoze golang pouziva mierne upraveny algoritmus, ktory vymyslel jeden z autorov. Ma niekde vycapeny aj dokaz korektnosti, ale o podrobnosti som sa nezaujimal.
Go používá tricolor GC.
-
Nevhodne nakladani s pameti zpusobuje presne, co jste popsal. Immutable objekty, zpracovani velkeho mnozstvi dat ve streamu by mohlo pomoct.
Není naopak naprosto obráceně lepší se těch immutable objektů zbavit? Mít jeden objekt který mění vnitřní stav je přeci pro GC mnohem lepší než pořád vytvářet nové immutable objekty!
Funkcionální struktury jsou často lepší. "Vnitřní stav" může být často dost divoký.
-
Mám dotaz, na který se mi nepovedlo vygooglit odpověď: Proč je latence GC v Go o tolik menší než v Javě? Při velké haldě (nad řekněme 16GB) se Java zasekává na vteřiny, kdežto Go zamrzne jen na pár milisekund. Cvičně jsem nahrál do paměti celou naši firemní databázi (přes 10 GB) a při práci s vše jede Go hladce, zatímco Java "stops the world". Testováno na Linuxu, Java je od Oraclu, Go verze 1,5.
Java má zásadní problém, že vše alokuje na haldě. V Go vzniká z principu mnohem méně odpadu a ve spojení s kvalitním (tricolor) GC se ta troška uklidí rychle. ObjC také mělo podobně kvalitní tracing GC, než zavedli ARC, jež mimochodem slouží stejně dobře.
-
Nevhodne nakladani s pameti zpusobuje presne, co jste popsal. Immutable objekty, zpracovani velkeho mnozstvi dat ve streamu by mohlo pomoct.
Není naopak naprosto obráceně lepší se těch immutable objektů zbavit? Mít jeden objekt který mění vnitřní stav je přeci pro GC mnohem lepší než pořád vytvářet nové immutable objekty!
Jedine pokud ten objekt, ktery meni stav se nedostane ven z funkce resp. vlakna. Jak se projekt rozrusta, tak se lokalni promena zacne zapisovat do cache atd.
Cokoliv, co je sdilene mezi vlakny - vyuziva cache nebo treba i jen session. Pokud je takovyto objekt sdileny tak mate problem napr. v transakcich, synchronizaci etc. Immutable objekt tento problem nemusi resit.
Tech vytvarenych objektu je naopak mene. Pokud menim immutable objekt (s pouzitim builder objektu), tak se vytvori tyto objekty:
builder a prevezme cleny z immutable objektu, ta cast, kterou je potreba zmenit a vysledny novy immutable objekt.
Pokud chci udelat zmenu objektu, ktery neni immutale, tak abych neovlivnil existujici objekt, tak musim udelat clone. To znamena vytvorit kopie uplne vseho bez ohledu na to, co budu menit. Pocitejte s tim, ze budete narazet na kod:
objekt = objekt.clone()
metoda(objekt)
a ve funkci metoda(objekt){
objekt = objekt.clone()
....
}
protoze si nebudete casem jisti, jestli vse co vola funkci metoda udelalo clone pred zavolanim funkce metoda a protoze je mozne vsechno menit vsude, tak to taky budete delat.
immutable objekty vypadji jako nanic, nez se dostanete k reseni podivnych chyb zpusobenych problemy se synchronizaci a kdyz se pokusite vyuzit distribuovane cache cely problem ziskava novy rozmer :)
Jestli chcete priklady, tak treba Date mel byt immutable, formatter taky, u Stringu se nikdo nepozastavi nad tim, ze je immutable.
Kolikrat jste uz videl toto?
public class Constants {
public static final SimpleDateFormat date = new SimpleDateFormat("dd.MM.yyyy");
}
Prepis kodu, ktery vyuziva "mutanty" na kod, kde se vyuzivaji immutable objekty je ocistec a rewrite byl nakonec lepsi volba.
-
Nevhodne nakladani s pameti zpusobuje presne, co jste popsal. Immutable objekty, zpracovani velkeho mnozstvi dat ve streamu by mohlo pomoct.
Není naopak naprosto obráceně lepší se těch immutable objektů zbavit? Mít jeden objekt který mění vnitřní stav je přeci pro GC mnohem lepší než pořád vytvářet nové immutable objekty!
Funkcionální struktury jsou často lepší. "Vnitřní stav" může být často dost divoký.
Záleží na definici pojmu "lepší". Faktem zůstává že funkcionální přístup často velmi zatěžuje GC, což v konečném důsledku má velmi negativní vliv na výkon. Programátoři ze staré školy (před používáním GC) kteří dokáží ukočírovat vnitřní stav objektů pak dodávají mnohem výkonnější řešení!
-
Nevhodne nakladani s pameti zpusobuje presne, co jste popsal. Immutable objekty, zpracovani velkeho mnozstvi dat ve streamu by mohlo pomoct.
Není naopak naprosto obráceně lepší se těch immutable objektů zbavit? Mít jeden objekt který mění vnitřní stav je přeci pro GC mnohem lepší než pořád vytvářet nové immutable objekty!
Z pohledu GC je mnohem lepsi objekt, ktery chcipne driv, nez se dostane z edenu nebo objekt, ktery zije hodne dlouho - kdyz uz to musi byt. GC edenu je rychle a levne. GC tenured je to, co zpusobuje casem full gc a zastaveni na nekolik sekund.
-
Nevhodne nakladani s pameti zpusobuje presne, co jste popsal. Immutable objekty, zpracovani velkeho mnozstvi dat ve streamu by mohlo pomoct.
Není naopak naprosto obráceně lepší se těch immutable objektů zbavit? Mít jeden objekt který mění vnitřní stav je přeci pro GC mnohem lepší než pořád vytvářet nové immutable objekty!
Jedine pokud ten objekt, ktery meni stav se nedostane ven z funkce resp. vlakna.
Aha, takže "jenom" ve většině případů? Pochopení tohoto je klíčem k pochopení toho proč jsou čistě funkcionální jazyky naprosto nepoužitelné pokud je potřeba brát ohled na výkon!
-
Nevhodne nakladani s pameti zpusobuje presne, co jste popsal. Immutable objekty, zpracovani velkeho mnozstvi dat ve streamu by mohlo pomoct.
Není naopak naprosto obráceně lepší se těch immutable objektů zbavit? Mít jeden objekt který mění vnitřní stav je přeci pro GC mnohem lepší než pořád vytvářet nové immutable objekty!
Funkcionální struktury jsou často lepší. "Vnitřní stav" může být často dost divoký.
Záleží na definici pojmu "lepší". Faktem zůstává že funkcionální přístup často velmi zatěžuje GC, což v konečném důsledku má velmi negativní vliv na výkon. Programátoři ze staré školy (před používáním GC) kteří dokáží ukočírovat vnitřní stav objektů pak dodávají mnohem výkonnější řešení!
V Javě jo, ale v jazyce se slušnou escape analýzou se většina objektů do GC vůbec nedostane. Přinejmenším ve standardní knihovně bývá práce s pamětí často velmi efektivní (to se týká i Swiftu, kde takto zase odpadá počítání referencí).
-
Mám dotaz, na který se mi nepovedlo vygooglit odpověď: Proč je latence GC v Go o tolik menší než v Javě? Při velké haldě (nad řekněme 16GB) se Java zasekává na vteřiny, kdežto Go zamrzne jen na pár milisekund. Cvičně jsem nahrál do paměti celou naši firemní databázi (přes 10 GB) a při práci s vše jede Go hladce, zatímco Java "stops the world". Testováno na Linuxu, Java je od Oraclu, Go verze 1,5.
Java má zásadní problém, že vše alokuje na haldě. V Go vzniká z principu mnohem méně odpadu a ve spojení s kvalitním (tricolor) GC se ta troška uklidí rychle. ObjC také mělo podobně kvalitní tracing GC, než zavedli ARC, jež mimochodem slouží stejně dobře.
Java má pro lokální proměnné stack (https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.5.2). Instance objektů se tam neukládají, ale používají se lokální reference, které se velmi rychle uklidí při ukončení metody, aniž by to muselo projít přes GC. (Pokud tyhle objekty obsahují instance jiných objektů, tak ty jsou alokované na haldě globálními referencemi, ale pochybuji, že by v Go existoval algoritmus, který by se tomu dokázal vyhnout. Takové alokace jsou běžně i v C++, ale tam to dost řeší RAII.)
CMS v Javě je taky tricolor, protože to je podstata paralelního mark+sweep.
-
Pro javu existuji i alternativni jvm.
Napriklad Azul ma jvm, ktera pouziva tento gc https://www.azul.com/resources/azul-technology/azul-c4-garbage-collector/
Pouzivate to nekdo?
-
https://www.youtube.com/watch?v=aiv1JOfMjm0
a btw java ma tiez escape analysis, ale nie compile time.
-
https://www.youtube.com/watch?v=aiv1JOfMjm0
a btw java ma tiez escape analysis, ale nie compile time.
Escape analýza v Javě je dost mizerná. Možná ji v deváté verzi vylepší, ale zatím jim moc nefunguje (v porovnání třeba s Go, ale i C#).