Diky za pekny clanek. V clanku zminujete jconsole - neplanujete jiny clanek o debugovani Java aplikaci? Neco na tema jak zjistit, kde moje aplikace drhne, jak spravne natavit heap a dalsi parametry, atd. Diky.
Názory k článku
Využití komprimovaných ukazatelů na objekty v JVM
Re: Moc pekny
celé vláknoo necem podobnem jsem premyslel, chystam se na popis garbage collectoru (v JDK6 a 7 jich je soucasne pouzito vice) a urcite neco o jconsole a podobnych nastrojich (VisualVM napriklad) bude.
Trove
celé vláknoMozno trocha pomimo, ale vela pamate sa da usetrit aj v pripade, ked potrebujeme pouzit kolekcie pre ukladanie primitivnych typov. Do standardnych java collections je mozne davat iba objekty a teda primitivne typy sa boxuju na ich objektove verzie. Toto zbytocne "zerie" vela pamate. Riesenim su primitivne kolekcie, napriklad pomocou kniznice Trove (http://trove.starlight-systems.com/).
nechápu
celé vláknonechápu, jakto, že tím, že se neuloží čtvrtina adresy(která je samozřejmě naprosto zbytečná - za starých dob bývalo přece paměť adresovaná segment:offset a segment byl pro celý kod/data/zásobník stejný, a tím se šetřilo prostorem) no, ale jak se může vynecháním zbytečné čtvrtiny ušetřit tři čtvrtiny místa? Ono to nebude jen šetřením v ukládání ukazatelů, že? (Buď jsem nečetl důkladně, nebo jsem měl číst ještě něco navíc)
Re: nechápu
celé vláknoUklada se jen polovina adresy tj. 32 bitu namisto 64 bitu (navic posunuta o tri bity doprava). O usetreti 3/4 jsem snad nikde nepsal, jestli to z textu nekde plyne, tak je to spatne ;-)
Jinak segment:offset - to platilo za dob 16bitoveho realneho rezimu, kde to byl ale peknej opruz, protoze Intel evidentne okopiroval tuto funkcionalitu z jinych procesoru aniz by si uvedomil, ze proste 16bitu na offset je na osobnich pocitacich malo (a jiz pri navrhu programu bylo nutne uvazovat o datovem modelu tiny, large, huge atd.).
A v chranenem rezimu s 32bitovymi offsety se na pointerech nic neusetrilo, ovsem zde mel segmentovy registr (resp. po novem selektor) jiny vyznam - urcovat jak bazovou adresu a limit "segmentu", tak i pristupova prava. S flat adresami to trosku ztratilo vyznam.
Re: nechápu
celé vláknoA existuji/planuji se na X86 nejake instrukce, ktere by takove baleni/rozbaleni adresy mezi 64 a 32 bity podporovaly? Nebo to JVM dela rucne?
Nicmene, takova instrukce je presne duvod, proc si myslim, ze 64bit neni konecne slovo - konecne slovo bude asi takovyto 32/64bit hybrid.
Re: nechápu
celé vláknoA 32b taky nebylo konečné slovo, ale dnes máme 16b/32b hybrid? IMHO jde spíše o přechodný stav. I když, kdo ví, možná se to uchytí. Ale vzpomeňte si na doby, kdy stačilo 640KiB...
Re: nechápu
celé vláknoNo, meli jsme 32/16 bitu hybrid - vyse zminenou segmentovanou architekturu 8086. Jestli je to posledni slovo - to asi neni uplne presne, podobne jako distribuovane systemy nejsou posledni slovo nad centralizovanymi. Oboji ma sve vyhody a nevyhody, takze to patrne vznikne a bude koexistovat.
Ale napriklad takovy z/OS by bylo mozne oznacit za hybridni 32/64 bitovy operacni system.
Jako vždy super článek
celé vláknoV poslední době čtu na rootu téměř výhradně jen články od Pavla :-)
Re: Jako vždy super článek
celé vláknoNo jo, vy z Redhatu ctete asi pouze odborne clanky ... suchari :-P
Proč 3 bity a ne 4?
celé vláknoNemám přesné informace o reprezentaci objektů v paměti, ale pochybuju, že se dostane na 8 bytů. A i kdyby, tak takových objektů bude naprosté minimum.
S ohledem na dnešní standard zarovnání paměti na 16 bytů (aspoň na nejrozšířenější x86/x86_64 - např. kvůli movaps, ale obecné vhodnosti pro jakoukoli 16byte operaci) bych čekal, že v návrhu useknou 4 bity. Vidím samá pozitiva, nebo se pletu?
Re: Proč 3 bity a ne 4?
celé vláknoKdysi jsem meril velikost objektu (pomoci mereni spotreby pameti) a vychazelo mi ze java.lang.Object ma 16 bajtu a kazdy object spotrebuje nasobek 8 bajtu (takhle to bylo uz na 32 bitech). Zarovnani na 8B je tam tedy vzdy, zarovani na 16B kupodivu ne.
Napada me dve negativa: Nejpis se uziva adresovani s indexem nasobenym 8, a nasobeni 16 architektura amd64 neumi. Taky by se utracelo az 8B na objekt a to muze byt uz hodne - netusim jaka je prumerna velikost objektu v prumernym programu.
Re: Proč 3 bity a ne 4?
celé vláknoHm, díky za měření. Asi bychom u hodně malých objektů (Integer, Long, ...) přišli o pár bytů. Maximálně 1/4, to by asi nebyla taková tragédie.
To adresování mě později taky napadlo, chtělo by to vidět implementaci, třeba se Pavel Tišňovský rozepíše v dalším dílu :) V každém případě by to znamenalo, že si java musí držet nějaký zero register, bo, pokud vím, tak bázový registr je při adresování s indexem povinný.
Re: Proč 3 bity a ne 4?
celé vláknoS tim bazovym registrem mate pravdu, jeste ze mame dalsich osm pracovnich registru :-). Dekodovani adresy vypada nasledovne. Ddoufam ze je ten kod je aspon trochu citelny, je to description file pro JIT i interpretr:
// Indirect Narrow Oop Plus Offset Operand
// Note: x86 architecture doesn't support "scale * index + offset" without a base
// we can't free r12 even with Universe::narrow_oop_base() == NULL.
operand indCompressedOopOffset(rRegN reg, immL32 off) %{
predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8));
constraint(ALLOC_IN_RC(ptr_reg));
match(AddP (DecodeN reg) off);
op_cost(10);
format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %}
interface(MEMORY_INTER) %{
base(0xc); // R12
index($reg);
scale(0x3);
disp($off);
%}
%}
Baze ma jeste vyznam pri rozpoznani typu ukazatelu, jeste se o tom nekdy zkusim rozepsat.
Re: Proč 3 bity a ne 4?
celé vláknoKupodivu ta hodnota granularity neni (prozatim) volitelna, i kdyz by teoreticky bylo mozne napsat patch, ktery bude posunovat adresu o 4 bity. Zkusim projit mail listy, kde se o tom pred cca 2 roky zacalo diskutovat.
Re: Proč 3 bity a ne 4?
celé vláknoAsi ne, soudě podle příspěvku výše:
format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %}
Takže je to asi tak, jak psal Maaartin, tedy místo rbx *= compress_bits a mov rax, [rbx] se píše rovnou mov rax, [r12+rbx*8]
A těch 8 (3 bity) je omezení dané platformou, z r12 si java asi udělala zero register. Ostatní řešení s násobením by asi způsobily znatelné zpomalení kódu, takže je to celkem pochopitelné.
Re: Proč 3 bity a ne 4?
celé vláknoJe to v podstate tak, jak pises - r12 je rezervovane jako zero register, ale ne pro vsechny operace. Pouziva se v nekterych pripadech take pro meziulozeni SP (presneji RSP) a pro uschovu adresy objektu. Takze ne vzdy je zaruceno, ze r12=0 ;-)
OT: lol url
celé vláknov url je až moc vidět nelámatelná mezera... trošku překáží v čitelnosti url...
Omezení 32bit
celé vlákno>> Kvůli použití 32bitových ukazatelů (včetně 32bitového PC a ESP) je možné adresovat a tím pádem i využít
>> „pouze“ adresní prostor o velikosti 4 GB (232 bajtů), do něhož jsou však kromě vlastní operační paměti
>> adresovány například i oblasti paměti dostupné přes PCI sběrnici či port AGP (typicky se jedná o
>> framebuffer grafické karty) a část z tohoto rozsahu si nárokuje i samotné jádro operačního systému
>> (v případě Linuxu až 1 GB adresního rozsahu).
TO IMHO není pravda. V 32bit logickém prostoru, kam ukazují ukazatele přeci není žádný framebuffer ani paměť mapúovaná přímo harwarem. Ta je přeci mapovaná do fyzického adresního prostoru.
IMHO právě směšujete logický paměťový prostor, kde si ukousne kus samotný OS, (např. Windows celé 2GB), ale jinak nikdo nic, a fyzický, kde si taktéž kousek ukousne OS, ale hlavně velký kus hardware.Fyzický adresový prostor ale není v 32 bitovém systému omezen na 4GB, i v 32 bit systému je přístupno více fyzické paměti.
Akorát většina verzí 32bit windows zároveň zavedla umělé omezení na 4GB fyzického paměťového prostoru (prý z důvodu, že některé drivery s víc pamětí neuměly pracovat, ale asi marketing) a tak přesvědčili lidi, že je to nutné kvůli 32bitovosti...
Re: Omezení 32bit
celé vlákno32-bitový proces v 64bitovém prostředí Windows s podporou /3G umí alokovat až 4GB, přičemž OS zabírá jen nutné minimum v podobě knihoven wrapperů z 32 na 64 (KERNEL32.DLL, atd...) OS si nevyhrazuje žádné gigabajty, protože sám je 64bitový a může běžet naprosto mimo adresový prostor aplikace.
Re: Omezení 32bit
celé vláknoJe a není. Aby se dalo s HW pracovat, je třeba jej namapovat do logického adresního prostoru (neplatí vždy - třeba na klávesnici stačí IO porty, aspoň ty staré, časy se možná změnily :) ). U grafické karty bude nejspíš stačit do user space pro X, u jiného HW do kernel space (a tam to bude viset pořád).
S tím umělým omezením - některý ISA HW snad potřeboval dokonce paměť pod fyzických 16MB, je dost možné, že novější měl limit pod 4GB. Ale je samozřejmě možné, že primární problém u Windos byl s oblíbeným DWORD kódem :)
Re: Omezení 32bit
celé vlákno>> S tím umělým omezením - některý ISA HW snad potřeboval dokonce paměť pod fyzických 16MB...
To je pravda, vsak jeste dnes lze u nekterych BIOSu najit prepinac "Memory hole at 15MB", tj. vytvoreni "diry" v pameti mezi 15MB a 16MB.
Re: Omezení 32bit
celé vláknoimho pokud je z userspacu pristup do framebufferu, tak prece je mapovan do logickeho adresoveho prostoru ne? hmm musim se do toho programu, ktery prisupoval do framebufferu podivat, co se vlastne volalo za funkce jadra, mozna to je reseny jak na starych VESAch 1.x pomoci vypadku stranek.
Re: Omezení 32bit
celé vláknoJo. Otevře se /dev/fbX, a poté se buď zapisuje přes write, nebo se namapuje přes mmap do logického paměťového prostoru programu.
Taková by byla základní funkcionalita. Používá-li se framebuffer i na konsoli, tak to znamená, že přístup musí mít i kernel, takže je přinejmenším část mapováná i do kernel address space. Rovněž novější grafické karty už mají drivery částečně v kernelu, takže i z toho důvodu okupují i část kernel space (pokud nepřepnou kontext vždy na X-server a nepracují nad user address space - zas tak dobře se v tom neorientuju). Ale to už je trochu OT.

