Nemyslím, že je java zrovna nenažraná co se týká JVM. Celkově jsou tady hlavní problémy dva. Prvním je neznalost programátorů, kteří často neví, jak se JVM chová k jejich datům v paměti, jak alokuje a uvolňuje prostředky. Neumí správně optimalizovat kód aby nevytvářel zbytečně nové "short lived" instance objektů, tedy nerecykluje. Využití profileru je bohužel u takových jedinců velkou neznámou. Druhým problémem pak je uživatel co aplikaci spouští s "default" nastavením JVM. Když mu dám 1 GB paměti, tak si to JVM prostě vezme, pak tu jsou ty neopodstatněné stížnosti na nenažrané aplikace, bohužel je to jen neznalost.
Když jsem psal aplikaci (computer vision a machine learning), tak mi úplně stačilo 64 MB aby to celé nespadlo na nedostatek paměti, ale čas procesoru strávený v GC byl už nad 10 %. Naopak, když jsem aplikaci dal 2 GB, tak se GC nespustil téměř nikdy, ale už je to celkem pořádný kousek paměti oproti minimu. Tím chci říct, že vždy jde o nalezení kompromisu mezi spotřebou RAM, CPU a programátorskou leností.
ZGC a Shenandoah GC tento koncept kompletne rusia. Oba pouzivaju particie. Shenandoah fixne, ZGC variabilne velke. Oba sa uz nespoliehaju na generational hypothesis ale razia cestu kooperativnej concurrent kompakcie. Shenandoah myslim aplikuje aj back pressure na rogue thready, ktore vela alokuju.
Nesetrna praca s pamatou aj vyplyva z principu, ktory JVM presadzuje: ked je kazdy objekt alokovany na heape a vsetko je by reference, tak holt musi pocitat s tym, ze bude vela kratko zijucich objektov. Keby bolo mozne alokovat na stacku, a bolo by mozne pouzivat by value, tak to by uvolnilo tlak na pamat.
Rovnako profiler: ked ma programator aplikaciu, kde mu bezi cely jboss, spring, hibernate plus nejake dalsie velke frameworky, tak sa necudujem, ze sa na neho vykasle. Vtedy je docela rad, ze to vobec funguje v ramci terminov, v ktorych sa moze pohybovat.
Není jedním z hlavních „selling points“ Javy to, že se člověk nemusí starat o nízkoúrovňové věci jako je to, jak se JVM chová k datům, jak jsou tato data representována v paměti apod.? Pro většinu aplikací je dnes výkonu a paměti dost, takže není divu, že většina vývojářů tyhle nízkoúrovňové záležitosti neřeší. Další generace už to třeba ani nebude umět.
Další problém je to, že normální vývojář zákaznické aplikace pracuje s řadou různých knihoven a nemá čas na to, aby je všechny detailně zkoumal, nebo si psal vlastní. Takže i když budu optimalisovat co to jde a psát perfektní kód, stačí jedna problematická knihovna a chování celé aplikace jde do háje.
Ad garbage collector: mně více vyhovovalo ARC v ObjC, ale i s GC se žít dá. Velké problémy mi způsobil jen jednou (import a zpracování velkého množství nevhodně strukturovaných dat na hodně slabém hardware).
Při přebírání zákazníkem to většinou nějak přijatelně funguje a dál holt spousta lidí nedohlédne, nebo to neřeší, protože jim většinou nikdo nezaplatí za to, aby nějaká funkce/aplikace byla napsána čistěji a běžela o 5 % rychleji nebo potřebovala o 2 MB méně paměti. No a když podobně postupují autoři knihoven a operačních systémů, tak se těch 5 % postupně nastřádá a je veselo.
IMHO jsou tyhle problémy odvrácenou stranou toho, že programování je čím dál tím více odděleno od železa a operačních systémů různými abstrahujícími vrstvami. Což má samozřejmě i spoustu výhod a je to svým způsobem nezbytné, protože v assembleru dnešních CPU se uživatelské aplikace reálně moc psát nedají.
Ehm ... ne, nefunguje to ani pri predani. Opakovane a cim dal castejs se setkavam s tim, ze patlal prinese svuj vytvor, predvede ho na svych 10 zaznamech a ja mu to cely zbouram tim, ze mu tam tech zaznamu pustim 10 ... Mega.
A pak se dejou veci ... protoze ten idiot se trebas tech 10mega zaznamu snazi nacist do ramky ... nebo (protoze to je uber dizajn kodu) tam ma nejakou rekurzi, takze s kazdym dalsim zaznamem se zdvojnasobi cas pro ziskani vysledku .... atd atd.
A to vsechno proto, ze ten patlal nema ani paru o tom, jak ten HW(a vlastne i SW) pod tim vlastne funguje a co umi a co ne.
Já jsem taky rozkopal spoustu báboviček různým bastlířům (a ano, ty konkrétní záležitosti, které uvádíte, jsem také zažil). Jenže ne vždy software přebírá někdo, kdo tomu rozumí tolik, jako Vy nebo já... A i pokud tam někdo takový sedí, ne vždy má právo veta resp. dost pevnou posici na to, aby odolal nátlaku managementu, který si to potřebuje odškrtnout jako „vyřešené“ s tím, že „drobné nedostatky“ se nějak doladí později.
Pro většinu aplikací je dnes výkonu a paměti dost? Jo? Tak si těch aplikací, pro které je dnes výkonu a paměti dost zkuste spusit deset vedle sebe. Ano, někde na serveru v jednom kontejneru, kde z principu nic jiného než váš javový backend neběží je to v pohodě. Jenže už když začnete něco stavětjako microservices, začnou tak nějak docela problémy. O desktopových aplikacích ani nemluvě.
Tohle "začnete něco stavět jako microservices" zrovna zní jako typický případ, kdy se nevyplatí investovat čas a prachy do nějaké přehnané optimalizace. Jo, můžeš si to napsat celé v C nebo assembleru a uplatnit v tom všechny Berkeley/MIT/Matfyz triky, co znáš, ale pokud to není vyloženě trivialita, bude ti to nejspíš trvat násobně déle než v Javě. A celou tu dobu, co tím strávíš navíc, bys mohl dělat něco jiného. Mnohé firmy si už dávno spočítaly, že čas vývojářů je příliš cenný prostředek, než aby si mohly dovolit jím plýtvat na něco, co se dá jednoduše vykompenzovat navýšením výpočetního výkonu. Což samozřejmě neznamená, že bychom se měli na optimalizaci vykašlat úplně, spíš myslet na to, že technicky dokonalé řešení je v praxi mnohdy zbytečný overkill.
No jasně, nikdo (příčetný) je nebude psát v C nebo assembleru, ale Java (resp. JVM) je také docela nevhodné právě kvůli době startu a paměťovým nárokům. Paradoxně mnohé z těch alternativ mají naopak ještě horší než Java/JVM (node, cpython), ale to se 90% ani nedá poznat, protože to stejně celé 99% času čeká na I/O nebo dokonce na uživatele.
Jasně, C a assembler jsou nadsázka, jen zkrátka poukazuji na to, že je v mnoha případech kontraproduktivní snažit se o maximální technickou efektivitu za každou cenu, protože technická efektivita nejde vždy ruku v ruce s produktovou nebo ekonomickou efektivitou. Java se pochopitelně nehodí na všechno, to se dá ovšem říct o každé technologii. Pokud ji použiju na aplikaci typu Hello World, která se spustí, vykoná pár triviálních kroků a skončí, tak ta efektivita samozřejmě bude beznadějná a bude to použitelné leda na věci, které se spouštějí jednou za čas (a i tak to bude prasárna, pokud lze to samé provést třeba jednoduchým shell scriptem). Pokud ji použiju na serveru v aplikaci, kde režie JVM tvoří zlomek celkového využití prostředků, tak získám robustní řešení bez velkých provozních nákladů navíc (a ty se mi snadno vykompenzují právě tou robustností, rychlejší implementací, snazší údržbou, nároky na schopnosti vývojářů atd.). A mezi těmihle póly je celá škála případů, kdy je třeba se rozhodnout, zda je Java ještě vhodná či použitelná, nebo už nikoli.
SubstrateVM (nativní image u GraalVM) je sice pěkná věc, ale není to univerzální řešení. Musíte přijmout nějaká omezení, která musí splnit nejen váš kód (to je většinou celkem řešitelné), ale taky kód všech použitých knihoven – a to je někdy problém i se standardní knihovnou z JRE.
V praxi to vypadá asi takto: Větší aplikace jsou se SubstrateVM prakticky bez šance. Menší věci – pokud překousnete několikamegovou binárku (dnes snad není problém) – s trochou štěstí půjdou zkompilovat a bez problémů pojedou. Ale ne vždy, třeba u JDBC jsem si vylámal zuby.
A má to nějaké bugy (typicky se naštěstí projeví hned při kompilaci), na které není tak těžké narazit. A občas se mi stalo, že nějaký platform-specific code to považovalo za reachable a při kompilaci pro Linux jsem tomu musel na classpath dodat i třeba JNA pro Windows.
Zatím taky je omezený seznam platforem, kde to jede. Windows není zatím podporovaný, macOS nevím, z instrukčních sad jen x64. Což je vzhledem k potenciálu pro embedded škoda.
Stručně, je to užitečná věc, ale má celkem omezené možnosti. Do budoucna to může být i o poznání užitečnější, ale patrně nikdy nepůjde o obecnou náhradu za univerzální JVM.
Že to nefunguje pro větší aplikace nevadí, protože u nich je vám jedno, že startují déle. Aby to byla univerzální náhrada za JVM není potřeba, protože ta AoT kompilace je součástí GraalVM, takže její výhody můžete využít i tam. To vytváření nativního obrazu míří především na microservices spouštěné v cloudu, kdy obsloužení jednoho HTTP požadavku znamená spuštění a ukončení procesu. Půjde to použít i na nějaké utility, ale myslím že není ambice spouštět tím jakýkoli kód, není to potřeba.
Jinak GraalVM je teď ve verzi 1.0-rc6, takže je úplně na začátku.
Pod Macem to funguje, pod Windows zatím ne, protože po tom není poptávka. Pod Windows dříve nefungoval ani Apache HTTP Server, PostgreSQL, vim – samé nepoužitelné programy. Které všechny platformy podle vás musí nějaká funkce podporovat, aby byla použitelná? Stejně tak je to použitelné i na větší aplikace – nezáleží totiž na velikosti aplikace, ale na tom, jaké používá funkce. GraalVM je zaměřený na budoucnost, ne na minulost. Takže momentálně nepodporuje třeba funkce, které mají modernější (rychlejší, bezpečnější) alternativy, a jejichž implementace by byla náročná. Důležité je, aby byla nová VM venku a mohla se používat alespoň pro něco, moderní aplikace z ní mohou těžit už teď. Staré neefektivní aplikace nejsou prioritou, když byly použitelné do teď s tradiční JVM, mohou tak fungovat i nadále.
Jak už jsem psal, Oracle tím s Javou míří do světa microservices a serverless architektury, kde teď Java nemohla moc obstát. Micronaut + GraalVM teď bude moci v této oblasti konkurovat NodeJS nebo Pythonu, přitom má za zády pořád celý obrovský ekosystém Javy. Monolitické Springovské aplikace bude možné postupně rozdělit na microservices, takže bude možné využít všech výhod cloudu nejen pro aplikace pro jednotlivce (jako dosud), ale i pro enterprise systémy (bankovní aplikace, telco, státní sektor). Vy si klidně dál spouštějte Springovský monolit pod Windows, ale smiřte se s tím, že ta vaše aplikace není celý svět.
Problém je, že to, co jste popsal není ve většině ostatních běžně používaných platforem víceméně vůbec třeba řešit. Takže nepište, že není. Je a dokázal jste to právě tím, co jste napsal. Bohužel je. Sice javu nepovažuji za něco extra překrásného -- na můj vkus je trochu robustní na cokoliv, co není vyloženě komplexní projekt -- ale kdyby se co se týká správy prostředků chovala více jako standardní binární aplikace nebo skriptovací engine, byla by rozhodně o dost použitelnější.