Co vím, tak jeden z předpokladů, který není v článku zmíněn a na kterém staví dnešní GC, je, že staré objekty zřídkakdy odkazují na mladé (obvykle to je naopak). Celkem by mě zajímalo, jak se tato vzácná situace řeší - napadlo mě, že by ten mladý objekt mohl být přesunut ke starším nebo případně naopak (a s ním mnohdy kaskádovitě i další objekty), aby tím nevznikala nekonzistence (při projítí mladších objektů nebude muset hledat ve starších, což by popíralo smysl generačního GC). Trefil jsem se, nebo je to řešeno jinak?
Druhá věc je, kdy tato situace obvykle vzniká. Představím-li si webový server, pak má obvykle objekty pro celý server (ty asi půjdou do nejstarší generace), objekty pro požadavek (asi málokdy pújdou do starší generace) a někdy i objekty pro session (ty nemusí jít do nejstarší generace, ale v nejmladší se taky asi neudrží), které budou sloužit asi spíše jako cache (např. při výpadku proudu by se mohly udržet). V tomto případě asi odkazování staršího na mladšího obvykle znamená spíše to, že ten mladší se bude chovat jako starší než naopak (když si představím takový přesun celého rozsáhlého LinkedListu do mladší generace... :-D)
Taky přemýšlím, jestli sessions nemohou být slabým (nebo aspoň nejslabším) místem ve výkonu správy paměti webového serveru.
Nakonec mě napadá, jestli existuje nějaká vláknově lokální generace, ve které se budou držet objekty, dokud na ně není odkázáni z jiného vlákna. Tato generace by mohla zvýšit výkon u jepičích vláken - pokud by nebylo toho naalokováno příliš, bylo by uklizeno vše najednou při konci vlákna.
To by bylo taky řešení, ale minule tu bylo zmíněno, že ve vícevláknovém prostředí je refcounting drahý. A přijde mi přirozenější to moje řešení. Ony jsou v případě, že mladší objekt ukazuje na starší, asi tři možnosti:
* Starší na něj ukazoval jen dočasně a pak si to 'rozmyslel'. Pokud na něj ukazoval jen malou chvíli, pak nevím, proč by to dělal. Pokud dlouho, pak nemusí být problém v převedení mladšího objektu do starších, protože bude žít déle.
* Starší na něj ukazuje až do konce svého života a tedy mladší bude žit minimálně tak dlouho, jako ten starší.
* Ona je tu nějaká třetí možnost? To asi teď vypadám, jako bych neuměl do *pěti* napočítat :-D
A při přesunu do starší generace by bylo tento flag nutno znovu prověřovat a při teoretickém dřívějším úmrtí jednoho ze starších objektů taky. A hlavně by to dočasně znamenalo častější prohledávání všech starších generací.
Lze to vylepšit zavedením flagu pro každou generaci zvlášť, ale pořád tu hlavní problémy zůstávají. A celkově mi přijde to moje řešení elegantnější - IMHO by ten objekt v té starší generaci stejně časem skončil.
Konkretne Sun JVM prilis neznam, ovsem:
Reference ze starsich do mladsich generaci se obvykle resi konstrukci jmenem "remembered set", coz je seznam do ktereho zapisova bariera ve starsi generaci zapisuje odkazovane objekty z dane mladsi generace, tato struktura se pak pri tech rychlejsich kolekcich pouziva jako dalsi koren.
Ohledne tech vlaken: pomerne caste reseni je, ze nejmladsi generace je opravdu nejakym zpusobem "lokalni" pro vlakno. Motivaci ovsem obvykle neni zrychlit GC, ale zrychlit alokaci pameti jako takovou (tj. odstranit nutnost synchronizace pri alokaci).
Kolik sofistikované práce musí GC dělat, aby pořešil lenost programátora.
A už vůbec mne vždycky překvapovalo, že v rámci GC cyklu objekty putují po paměti. Tolik zbytečného kopírování. A to jen proto, aby alokace mohla probíhat inkrementalně. Co ušetříme na alokaci, a kolik nás pak stojí dealokace?
To bych se hádal, protože defragmentace znamená, že bude pohromadě hodně nesouvislých objektů. Leda, že by se defragmentovalo nějak chytře, třeba odkazované objekty u sebe, například pole a instance uložené v poli.
Ja nevím, já třeba v C++ mám vlastní alokátor tzv "ClusterAllocator", který pro mnou vybrané situace dává objekty k sobě už od začátku a ta cache je též lépe využitá.
U vícevláknových aplikací je lepší, když každý vlákno má vlastní memory pool (což můj alokátor taky řeší). Tam je možná ten efekt markatnější a nejsem si jist, tak to řeší superglobální GC.
To je minoritní stav. Stejně jako hodně objektů vzniká a zaniká rychle po sobě, zanikají s nimi i instance alokátorů. A protože alokátory často alokují právě velikosti stránce v cache, fragmentace se neprojeví na výpadcích stránek v cache. To by musela být dejme-tomu mapa, která se naplní a pak se polovina prvků náhodně odstraní a ta mapa se pak používá po celou dobu běhu aplikace. Tam se samozřejmě ušetří tím, že tu mapu setřesu do menšího množství clusterů. Ale to se dá řešit operativně (tedy ruční překopírování mapy do nové mapy) v tom mizivém procentu případů.
Jeden z problémů Javy při nízkoúrovňových pracích s paměti je ten, že programátor nemá možnost prakticky nijak ovlivnit, jak se objekt skutečně vytvoří.
Neexistuje ani podpora v samotné syntaxi jazyka, kde by se třeba mohlo anotací sdělit "toto je jen lokální objekt v metodě".
Ovšem neexistuje ani podpora v bajtkódu, kde lze použít jen jeden typ instrukce pro alokaci objektu (na haldě a většinou v edenu). To je docela škoda, protože již překladač by mohl pomocí statické analýzy kódu některé objekty umisťovat například do zásobníkového rámce.
Ondro, prece ty jako programator v C++ taky musis byt udiven, kolik sofistikovane prace musi C++ compiler udelat, aby prelozit zdrojak do objektoveho kodu :-) Zrovna u C++ je ten kompiler hoodne slozitej rekl bych uz ve front endu, a to ani neuvazuji o optimalizacich v back endu.
Takze bych to asi chapal takto: dnesni programatori jsou (a mnohdy musi byt) lini, protoze deadline atd. Z toho duvodu vyuzivaji vysokourovnove jazyky, protoze se nikomu nechce moc patlat v assembleru, kor na tak pitome platforme jako je i386 ;-(
No a kdyz uz vysokourovnovy jazyk, tak si mnozi reknou, proc ne primo managovany jazyk? GC samozrejme neco stoji, ovsem odmenou je snizena pravdepodobnost vzniku memory leaku, lepsi soustredeni na vlastni algoritmus atd. Proto jsou dnes C, C++ a Fortran uz jedine pouzivane jazyky (no na M$win snad jeste Delphi), ktere nemaji implicitni GC.
OT: Proč jsem pod "M$win" viděl syntetickou metodu? Už mi asi hrabe.
http://wheelworkshop.blogspot.com/2005/09/emulated-by-synthetic-accessor-method.html
Memory leak? Ten jsem viděl naposledy minulý rok. A to po tom, co jsem si udělal bodu v nějaké lowlevel knihovně. Od čeho jsou v C++ chytré pointery :-)
Argument založený na rychlosti počítačů neobstojí. Proč jeden programátor napíše soft, který 400tis záznamů zpracovává dva dny a druhý totéž zvládne za půl hodiny? Ten první tvrdil, že není třeba optimalizovat, protože počítače jsou rychlé dost. Ten první program přitom běží na nabušené osmijádrové mašině, ten druhý na notebooku ve virtuálu se dvěma jádry a s omezenou velikostí paměti.
> Argument založený na rychlosti počítačů neobstojí.
Uz je to tu zas. Je rozdil mezi a) lemplem, b) programatorem, ktery za sebou nechava relativne jednoduchy a dobre navrzeny produkt vyuzivajici "zjednodusujici" technologie, c) optimalizatorem, ktery stravi mraky casu na urychlovani neceho u ceho to casto neni vubec potreba. Rikate, ze kvuli existenci a) neobstoji b) a je nutne se drzet c)?
Proto považuju GC za zbytečnost. Jestliže smyslem GC je urychlit alokace, tak přepsat kód tak, aby 10% kódu o kterém je známo, že provádí 90% výpočtu používalo zásobník, nebo alokátory se složitostí 1, je mnohem jednodušší a výsledkem může být rychlejší kód bez záškubů při řešení collectingu.
Mimochodem, mám napsaný GC pro C++
(http://bredy.novacisko.cz/?Garbage-collector-automaticky-uklid-objektu-v-C-/239)
Teda až na defragmentaci paměti, protože u ní bych musel vždy při přesunu objektu zajistit, že se s ním zrovna nepracuje, což znamená mutex a každý mutex znamená overhead v syncu (jak tohle řeší Java netuším).
Nicméně zásadní informace. Byť to funguje skvěle, zatím jsem to nikdy nepotřeboval. Dobrý projekt totiž má dobře navržený zodpovědnostní model. Každý objekt má na starost jiné objekty a ty vytváří a likviduje. Platnost je vždy předem známa. A sdílení objektů se děje opravdu minimálně a pokud se opravdu děje, tak klasický refcounting (bez zamykání i v MT) to pořeší.
> Dobrý projekt totiž má dobře navržený zodpovědnostní model. Každý objekt má
> na starost jiné objekty a ty vytváří a likviduje. Platnost je vždy předem
> známa. A sdílení objektů se děje opravdu minimálně a pokud se opravdu děje,
> tak klasický refcounting (bez zamykání i v MT) to pořeší
Nojo, ale jsou i "špatné" projekty, kde to prostě takhle nejde ;-)
Mně zas třeba netrápí řešení alokace zdrojů, protože v mých projektech jediné, co se musí explicitně uvolňovat, jsou DB spojení a o ta se mi postará automaticky Spring.
Zpravidla nejsou zodpovědné za jejich život. V dokumentaci se akorát uvede, že musí platit po dobu života konstruovaného objektu. Ten kdo objekt konstruuje pak nese zodpovědnosti i za objekty, které do konstruktoru předává. Pokud je třeba držet objekty spolu s nově vznikajícím objektem v jedné instanci, pak se třída podědí a do jejího destruktoru se přidá delete na ty objekty.
Složitější situace se řeší refcountingem, nebo sdílením (třída co sleduje život kopií jedné instance a sdílené zdroje uvolňuje v okamžiku, kdy se ničí a už je jedinou)
Proti cyklům ve sdílení lze bojovat tak, že se program navrhne jako DAG (Directed Acyclic Graph), a ukazatele jdoucí opačně se do refcountingu nezapočítávají
Uz jsem to psal zde
http://www.root.cz/clanky/monitorovani-procesu-a-sprava-pameti-v-jdk-6-a-jdk-7-2/nazory/373844/
nevim jak lip to mam rict. Nikde prece nepisu ze smyslem GC je urychlit alokace, spise je to hezky vedlejsi efekt. Ja jsem hlavne psal, ze to usnadni praci, zjednodusi navrh programu - tohle ma nedozirne pozitivni nasledky v dalsi udrzbe programu, atd. A mimo jine se taky muze stat, ze je program rychlejsi.
A vy prijdete a reknete, ze GC neni potreba, protoze to prepisete na zasobnikovou alokaci, napisete vlastni GC, nebo poresite zodpovednostni model, pripadne zavedete refcounting.
To je presne pointa mych prispevku - tohle s GC resit nemusite a vetsinou do dopadne dostatecne dobre. Kdyz napisu, ze s GC nemusite resit XY, tak se trochu motate v kruhu kdyz odpovite, ze nepotrebujete GC protoze se to da vyresit pomoci XYZ. Chapete?
Me zas obcas udivi jak se dela ctnost z toho, ze programator resi neco, co muze vyresit stroj, navic ve vetsine pripadu s uspokojivym vysledkem (ne-li lepsim).
> Co ušetříme na alokaci, a kolik nás pak stojí dealokace?
Konkretne o jvm GC bylo popsano spousta, tak jen zkratka. Alokace je v podstate jen posunuti pointeru v edenu, cili par instrukci na objekt. Jak je zmineno v clanku, u vetsiny aplikaci vetsina objektu neprezije do dalsiho uklidu edenu, nez se dostanou do old gen, tak jich zbyde par, cili u vetsiny objektu se dealokace vubec neresi za cenu toho, ze u tech zbyvajicich je to trochu narocnejsi. Navic GC bezi az kdyz pamet dojde, coz taky nemusi nastat vubec.
Na druhe strane je new/delete, kde nalezeni vhodneho volneho bloku je netrivivialni operace, podobne pri delete, ktere navic bezi pro kazdy objekt. Dale je tim postizen navrh programu, ktery musi objekty ke smazani nutne nejak evidovat, cimz vlastne cinnost GC supluje.
Takze ve vysledku lehce skoncite s vetsi rezii, spoustou zbytecnych operaci a slozitejsim algoritmem. Kdo se tomuhle vyhne pro me neni liny ale velmi mazany :-)
Vycházíte z obecných a mylných předpokladů
- dávno nepoužívám new/delete a pokud ano, tak na objekty dlouhého trvání nebo alokaci větších kusů z velké haldy
- dávno se nestarám o dealokací objektů
- valná většina alokací a dealokací má složitost 1
- masivně používám zásobník
Oproti GC to má obrovskou výhodu. Například tu, že destrukce se provede v okamžiku, kdy objekt skutečně ztrácí platnost a ne "až někdy", což je někdy hodně dlouhá doba. Pokud v javě chci přesně definovat konec platnosti, musím se o to zneplatnění postarat sám, jako v Cčku a nemám možnost automatického volání destruktorů...
pravda v JDK 7 je to lepší, pomocí try syntaxe, ale je to někde na půli cesty.
Ok, blbe jsem se vyjadril, nemluvim konkretne o vas, ale o obecnem projektu pro obecneho programatora v dobe 2Ghz 4jader a 4GB ram. Proste takovy, ktery nema zapotrebi resit kde co alokovat, jak to dostat na zasobnik, kdy to zmizi z pameti atd.
Ze jsem tak zvedavy - proc vam vadi, ze objekt z pameti zmizi za hodne dlouhou dobu?
Tak tak, na uvolňování zdrojů tu není GC, ale java.io.Closeable a případně i automatic resource management (Lombok, scala-arm, bude Java 7), pokud je vhodný. GC je prostě jen na situace, kdy není důležité, kdy je daný zdroj uvolněn. Stejnětak považuji za zvrhlé nechat GC uklízet handlery (někde jsem se o tom i rozepsal).
V situaci, kdy paměť je jeden z prostředů, čili nemá výsadní postavení před jinými (disk, síť, procesor), je GC zbytečný luxus. A nebo by měl řešit úklid i těchto jiných prostředků, například zavírat opuštěné soubory, či likvidovat opuštěná vlákna (v C++ běžně dělám to, že "zanechávám" běžící vlákno a destruktor zajistí jeho bezproblémové ukončení. V javě musí vlákno ukončit explicitně)
Jako náhrada tohoto použití destruktoru může být automatic resource management (Java 6: Lombok, Scala: scala-arm, Java7: ta vestavěná šílenost) - udělá prakticky to stejné. A nutí řešit výjimky ze zavírání, což je mimochodem celkem sranda, pokud je zavíráno více zdrojů.
A vlákna mi nepřijdou jako dobrý příklad - to prostě buď nechám doběhnout a ukončí se samo, nebo ho chci přerušit, tak mu pošlu signál. Zabít ho nemůžu - to je zakázáno např. kvůli rušení zámků.
O řešení v JDK 7 vím, už jsem to komentoval, je to rozhodně lepší, ale někde na půl cesty. Přitom mít možnost navázat destrukci objektu na likvidaci stackframe by se celkem dalo jednoduše implementovat.
Vlákna samozřejmě nezabíjím. Destrukor zároveň používám jako automaticky zavolanou funkci, která pošle signál a počká, až vlákno skončí. Nechat vlákno běžet dál, to je zlé. Pokud opravdu nemám přehled o tom, co zrovna vlákno dělá, mohlo by pracovat s nekonzistetními daty. GC mi sice zajistí, že data nikdo neuvolní předčasně, ale to není řešení. Kolikrát to může způsobit víc škody, než pád aplikace na SIGSEG. O pádu se programátor dozví hned, zápis do nekonzistetních dat se může projevit až po nasazení do provozu.
"Přitom mít
možnost navázat destrukci objektu na
likvidaci stackframe by se celkem dalo
jednoduše implementovat."
Implementační detail JVM - escape analysis :-) A jako handler s jistotou volání poslouží zmíněný automatic resource management.
K vláknům: Dost záleží, na co jsou používána. Pod tímto si představím spuštění někde v metodě jako něco paralelního pro urychlení výpočtu.
Tak si třeba představte UI na kompresi WAV do MP3. UI ukazuje progressbar a tlačítko cancel a křížek. Vlastní algoritmus musí běžet ve vlákně, protože UI musí reagovat na uživatele. Myslíte si, že je rozumné, aby takové vlákno pracovalo dál, když uživatel tohle okno zavře?
A to se dělá zavíracím tlačítkem? Aha... Už chápu, proč si s některými výtvoru Open-source programátorů nerozumím :-)
PS: V zadání bylo, že vlákno vytvořilo okno. Okno je zodpovědné za vlákno. Pokud by to mělo běžet na pozadí, musel by vlákno vytvořit někdo jiný, třeba objekt modelu a okno je pak view (controler). To je ale jiná situace, řeší se jinak, a také nepotřebuje vlákno bežící nekontrolovatelně dál.
Mimochodem, jak u takového nekontrolovatelného vlákna poznáte, že už je hotové?
No, múže se to dělat, záleží na designu aplikace. Prostě dáš "nová konverze", otevře se nové okno, v tom zadáš parametry, pustíš a buď počkáš na výsledek nebo okno zavřeš a děláš v aplikaci něco jiného a konverze zatím běží na pozadí, zobrazovaná třeba ve status baru. IMHO takový design smysl dává.
Jinak ano, máš pravdu, asi před deseti příspěvky se o tom mluvilo, že to vytváří okno, tak daleko jsem nedočetl.
V tom pripade asi bude problem ve vas vzhledem k tomu, ze jazyky s GC vladnou. Cili pred 10 lety existoval nejaky problem s uvolnovanim pameti a dnes je nejak zazracne vyresen nebo jak tomu mam rozumet? Nebo uz dochazeji argumenty?
Vy jste se proste rozhodl, ze GC je spatny, asi proto, ze uvazujete v duchu C++ a radsi resite veci sloziteji a po svem, nez je nechat stroji. To je holt vec natury, jen nechapu proc mate tu potrebu tohle ventilovat pod clanky o GC a rikat, ze jsou programatori lini kdyz to pouzivaji.
" dnes je nejak zazracne vyresen nebo jak tomu mam rozumet?"
Přesně tak! Ten kdo skutečně programuje objektově a má na vědomosti i to, že objekty nejen vznikají, ale i zanikají a má navržený správně model zodpovědností, nemusí tento problém vůbec řešit! A je úplně jedno, v jakém to je jazyce. Důležité je, že je třeba definovat přesný okamžik zániku objektu. Což objektový jazyk z GC není schopen, proto jej považuji za méně OOP, než C++
to že se při zániku objektu někde uvolňuje paměť je nepodstatné. v Javě je tohle postaveno nahlavu. Přednější je paměť, objekty jsou odsunuty na druhou kolej.
No, to je presne to o cem mluvim. Vy uvazujete v c++, takze berete jako dogma, ze si programator musi uvedomovat zivotnost, zanik objektu, to vede k tomu, ze musite tvorit model zodpovednosti, upravit algoritmus dle toho, pripadne to dohanet alokaci na zasobniku nebo pres refcount a pak vitezoslavne reknete problem vyresen.
Tak si zkuste predstavit, ze tohle vsechno hodite za hlavu, jen pohlidate uvolnovani zdroju (coz muze byt zanedbatelna cast programu) a mate to vyreseno taky. Se vsemi vyhodami ktere jsem zminil drive. Vy mate implikaci pisu program -> musim poresit uvolneni zdroju -> musim znat dobu zaniku objektu -> GC je spatny. Jenze ta druha sipka je jen vase dogma, ve skutecnosti se to da udelat jinak. Zkuste si to aspon predstavit! Dokud to tak budete brat, tak vam samozrejme GC bude vychazet jako spatny pristup a nepohnete se z mista a nema smysl o tom psat dalsi prispevek.
> Ten kdo skutečně programuje objektově...
To je nejaka uznavana definice "skutecneho oop"?
Vám přijde zodpovědné "zanechat jen tak objekt?". Kdo vám zaručí, že takto zanechaný objekt bude opravdu zničen a nebude vyvíjet nějakou další činnost? Co když Vám někdo předhodí objekt, který v sobě vytváří vlákno? Pak "zanechat jen tak" takový objekt je velice nebezpečné. A pokud nemáte jistotu, že opouštíte objekt v bezpečném stavu, musíte si bepečný stav zajistit nějak jinak... ručně, protože Java nemá nástroj na automatické sledování platnosti a zodpovědnosti
> To je nejaka uznavana definice "skutecneho oop"?
Velmi výmluvná otázka. Jsem si jist, že člověk, který by věděl o čem mluvím by se takhle neptal.
> Zkuste si to aspon predstavit!
Říkáte člověku, který několik let dělal v Javě :-D
Z principu OOP - objekt je černá krabička, která může dělat leccos. Je třeba se na ni divat jako na zařízení, které se zapíná (konstruuje) a když už ho nepotřebuju, tak se vypne (destruuje). Zanechávat zapnutá zařízení na skládce fakt není dobrý nápad.
U 99% javovských aplikací, protože stejně argumentuju, že javovské aplikace se speciálně navrhují aby vyhověli Javě.
No, i když přistoupím na tu "černou krabičku", tak ta buď má tlačítko "vypni" a pak ho musím stisknout, když už objekt nepotřebuji. Nebo ho nemá a pak se nemusím o vypínání starat a komplikovat si architekturu ještě nějakým "modelem zodpovědnosti". V praxi drtivá většina objektů takové tlačítko nepotřebuje a nemá.
Moje objekty vetsinou nedelaji zaskodnickou cinnost, takze je opravdu nezodpovedne nechavam lezet. Mozna to je taky to dedictvi c++, rozumny zpusob jak se vyporadat s vlakny, io apod. bylo zabalit to do objektu. Pak vam to skodi a musite resit zivotnost atd. Mam z toho pocit, ze jste tech nekolik let s tou javou docela zapasil. Znovu tedy apeluji na vasi predstavivost!
Ke skutecnemu oop - jen jsem se chtel vyhnout debate o tom, jak pracuje a mysli opravdovy oop programator, protoze to neni univerzalni.
Chápu. Ono, říkat vám pak, že na vlákno je často potřeba se dívat jako na objekt je tedy asi mrhání energií. Že to není kvůli neexistenci GC v jiných jazycích, ale prostě proto, že chci se na vlákno dívat jako na objekt, protože to spoustu věcí řeší samo...
Potvrzuje se moje doměnka, že v Javě programují ti, co OOP moc nepochopili.
> na vlákno je často potřeba se dívat jako na objekt
Uff, porad to same. To v C++ je to vhodne kvuli uvolneni, protoze to stejne pro objekty musite resit. Cili ne ze se to resi samo, ale resite to vy u vsech objektu v celem navrhu.
V jave je to sice fakticky objekt, ale kdyz se k tomu tak budete stavet, mate problem s GC. Coz je patrne prave zdroj vasich problemu. Tak jeste jednou. Uvolnete se, predstavte si ze uvolneni zdroje a dealokace objektu neni to same a GC se vam odmeni. Je to java, myslete v jave a ne v C++. Pokud vam neco zere zdroje vnitrne, tak je to spis problem v navrhu.
V jave jsem toho zatim moc nenapsal, uz mnoho let me zivi C++ (a ano, resim zivotnosti, zabaluju prostredky do objektu, pocitam reference a alokuju na zasobniku...)
"To v C++ je to vhodne kvuli uvolneni"
NE! je to vhodné kvůli oběktovému přístupu
"V jave je to sice fakticky objekt, ale kdyz se k tomu tak budete stavet, mate problem s GC"
Samozřejmě. Nemohu uplatňovat OOP přístup na vlákna v Jave, protože GC. A není to jen u vláken.
" Uvolnete se, predstavte si ze uvolneni zdroje a dealokace objektu neni to same a GC se vam odmeni. "
Nenohu. Klasické programování (takové, kde zdroje musím uvolňovat ručně) jsem zapoměl.
Mimochodem, že vás nenaštvě jako mne, kdykoliv se Eclipse zakousne na takové 2 - 3 sekundy, kdy provádí globální collect. A už vůbec mě vadí, že javovské aplikaci musím přidělovat nějakou paměť. Copak vím kolik? Bez ohledu na to, kolik mám v Eclipse projektů, vždycky ji nakonec vyplní celou a když jich tam mám náhodou moc, dokonce to narazí na limit a spadne a to přesto, že zrovna v systému volná paměť je.
Udedené záseky Eclipse jsem zaznamenal naposledy asi před několika lety na muzejní sestavě s WinXP, AMD Duronem 750MHz a 384MiB RAM.
S maximální pamětí celkem souhlasím ale pro mě to zatím v praxi nebyl závažný problém. Ale někdy to otravuje - naposledy asi na soutěži, kdy jsem psal zásobníkový automat, který měl zpracovat opravdu nechutné zanoření.