V .NET máme v podstatě zadarmo možnost obejít p-invoke a přistupovat k nativnímu kódu přímo z C#. Mnohdy je ale problémem pouze zacházení s pamětí a o nativní (resp. C(++)) kód nám vůbec nejde. V takovém případě máme k dispozici neřízenou haldu.
V Javě máme to samé, jen se o tom tolik neví. Samozřejmě bychom mohli k efektivnímu zacházení s pamětí použít JNI nebo JNA, ale mnohem multiplatformnější je využít třídu sun.misc.Unsafe. Už podle jména je jasné, že je určena jen pro experty (takže tak 2–3% javistů), ale výhody pak stojí za to.
Předně nám umožňuje alokovat paměť mimo haldu JVM (a tedy mimo GC). Typickým použitím je například rychlá serializace objektů. Metoda allocateMemory alokuje paměť a vrátí adresu vyhrazeného bloku. Metoda freeMemory blok uvolní. Je zřejmé, že si musíme dávat pozor na správné uvolnění alokované paměti, proto by se takový kód měl vždy vyskytovat v konstrukci
try (...) {...}
C++/CLI je sice v tomto podstatně dále, ale stále se jedná o velmi užitečnou a často používanou techniku, která aspoň částečně pomáhá vyvážit nevýhody GC. Skutečně výkonné aplikace se často spouští schválně s malou haldou, aby bylo k dispozici co nejvíce nativní paměti pro efektivní zacházení s ní.
P.S. Nebyla by to Java, kdyby vývojáře něčím neznechutila. Vytvoření objektu Unsafe je neuvěřitelně stupidní a i tak má překladač spoustu keců. Ale při vhodném zapouzdření se to dá zkousnout.
Clanek by se mohl jmenovat "Prasime v Jave, aneb chceme programovat v Jave jako v C++ a je nam to jedno".
Pouziti JNI/JNA/PInvoke stoprocentne zajisti, ze program bude neprenositelny a s velkou pravdepodobnosti zajisti i to, ze za deset let nebude zkompilovatelny ani na HW platforme, pro kterou byl puvodne urcen (empiricka zkusenost).
sun.misc.Unsafe je taky neprenositelny, navic clovek musi byt opravdu hodne zoufaly, aby to melo nejaky vetsi efekt. Vetsina tech veci ma svou prenositelnou variantu. Napriklad pro tu (de)serializaci je mnohem vyhodnejsi pouzit nektereho z potomku ByteBufferu.
Urychlení (de)serializace objektů je docela obecné... je to něco obdobného co dělá xstream?
http://svn.codehaus.org/xstream/trunk/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SunUnsafeReflectionProvider.java
Jinak Unsafe používá pro zrychlení například i guava (dříve google collections) pro rychlejší porovnávání obsahu polí.
@11 Zrovna pred pulrokem jsem resil, jestli ma smysl pouzit buffery nebo unsafe pro aplikaci intenzivne pracujici s daty a vysledek byl temer nemeritelny, stezi v jednotkach ms. Nejvetsi bottleneck byl (jako obvykle) IO.
@13 Jo, ti bajecni vyvojari nebudou muset dnes napsane aplikace za deset let pouzivat nebo snad supportovat a tak, stejne jako ty, muzou dal s klidem v dusi uctivat fetis rychlosti, aniz by je trapilo, ze casem kvuli temto nedokumentovanym funkcim, jejich vytvor nepujde spustit nebo prelozit.
Ja by som bol strasne zvedavy ako autor ziskal udaj kolko je percentualne expertov na Javu zo vsetkych Java programatorov. Ako sa da vobec k takemu konkretnemu cislu (2-3%) vobec dostat? Zauradoval postup "pozrel som sa do stropu s prstom v nose a vymyslel si bulharsku konstantu"?
Hezky clanek na toto tema;
http://mishadoff.github.io/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/
Padly zde dve protichudne informace:
1.) Unsafe se pouziva tam, kde zasobniky nepomuzou
2.) Delal jsem testy a rozdily zasobniku versus Unsafe a rozdily byly minimalni
Tak ted nevim teda.. :-)
@ded.kenedy
Muzesa postnout, jakym zpusobem jsi testoval?
Autor se zabývá vývojem kompilátorů a knihoven pro objektově-orientované programovací jazyky.
Přečteno 36 343×
Přečteno 25 471×
Přečteno 23 874×
Přečteno 20 264×
Přečteno 17 978×