...

Czterej jeźdźcy apokalipsy gdy Armagedon w JVM nadchodzi

by jaroslaw-palka

on

Report

Category:

Software

Download: 0

Comment: 0

549

views

Comments

Description

Download Czterej jeźdźcy apokalipsy gdy Armagedon w JVM nadchodzi

Transcript

  • Czterej jeźdźcy apokalipsy gdy Armagedon w JVM nadchodzi.
  • • chief architect @ Lumesse • owner/founder/one man orchestra @ symentis.pl • blogger @ geekyprimitives.wordpress.com • philosopher @ twitter:j_palka • code mangler @ bitbucket:kcrimson & github:jpalka • evil emperor @ 4developers conf/architecture track • restrained Padawan @ church of JVM
  • Celem tej prezentacji jest pokazanie Technik, których na co dzień nie będziecie Stosować Ten materiał zakłada, że na co dzień nie zgłębiacie terenów przygranicznych System operacyjny/maszyna wirtualna Zaprezentowane poniżej informacje i fakty mogą trwale odmienić wasze postrzeganie rzeczywistości
  • Dopiero zaczynasz z JVM? Zachwycisz się złożonością Masz już za sobą pierwszy pad produkcji? Przeklniesz złożoność JVM Chcesz wiedzieć więcej jak to wszystko działa? Ta prezentacja łagodnie wprowadzi Cię w terminologię i podstawy
  • Moją opowieść będę snuł wokół OpenJDK 8 i systemu operacyjnego Linux Część z tych rzeczy może być prawdą dla innych JDK i OS
  • Ale niekoniecznie :)
  • Opowieść czas zacząć
  • Pewnego pięknego zimowego wieczoru gdzieś w Krakowie, kilka lat temu
  • O godzinie 4.03 Gdy nadzieja już dawno opuściła biuro A zdrowy rozsądek już dawno wyskoczył za okno hg clone http://hg.openjdk.java.net/jdk8/jdk8
  • apt-get install sysstat apt-get install strace apt-get install sysdig sar -d -R 1 strace -f -T -p666
  • A mówiła mama nie zaglądać za zamknięte drzwi?
  • gdy wtem, nagle i znienacka ...
  • Z pyłu, sadzy i dymu, pierwszy jeździec się wyłonił A imię jego
  • Garbage Collector
  • Wiele zrobiono i napisano o automatycznym zarządzaniu pamięcią w JVM Gdy już ustawisz wszystkie parametry i przełączniki A GC nadal będzie zniewalało twój CPU Jedyne co pozostaje to „off heap memory”
  • java.nio.ByteBuffer.allocateDirect() „may reside outside of garbage collected heap” So called C-heap Makes famous sun.misc.Unsafe a little bit safer And slower:) But let's talk about sun.misc.Unsafe.allocateMemory
  • Allocation and deallocation is really expensive Mostly because of costly JNI calls and NMT (native memory tracking) Mail thread@hotspot-dev Unsafe allocate Calls OS malloc function hotspot/src/share/vm/prims/unsafe.cpp
  • UNSAFE_ENTRY(jlong, Unsafe_AllocateMemory(JNIEnv *env, jobject unsafe, jlong size)) UnsafeWrapper("Unsafe_AllocateMemory"); size_t sz = (size_t)size; if (sz != (julong)size || size < 0) { THROW_0(vmSymbols::java_lang_IllegalArgumentException()); } if (sz == 0) { return 0; } sz = round_to(sz, HeapWordSize); void* x = os::malloc(sz); if (x == NULL) { THROW_0(vmSymbols::java_lang_OutOfMemoryError()); } //Copy::fill_to_words((HeapWord*)x, sz / HeapWordSize); return addr_to_java(x); UNSAFE_END
  • Because it uses malloc You can „easily” provide your own allocator export LD_PRELOAD=mylib.so jemalloc (look cassandra case) Anyway, it all can end up with „core dump” So be carefull Or use wrappers
  • Tools to play with github:alexkasko/unsafe-tools github:peter-lawrey/Java-Chronicle apache-directmemory Who depends on unsafe ehcache (with BigMemory) hazelcast (with ElasticMemory) infinispan lucene cassandra
  • Trade offs, stupid!
  • Huge, really huge, Tottaly huge data structures Beware!!! lifetime of objects serialization/deserialization
  • … and then Jigsaw came And changed the game C-Heap API because people are actually using it (broken window) Unsafe at any Speed Public sun.misc.Unsafe Replacement API No plans for JDK9 so far
  • I ziemia się rozstąpiła I ogień piekielny z ziemi wypełzać począł drugi jeździec się wyłonił A imię jego
  • Input / Output
  • Block deviceDevice driver IO scheduler (merge/sort) I/O request
  • %iowait Device queue size Time spent on the queue iostat ­x ­d sda 1
  • avgqu­sz average queue length for this device await average response time (ms) of IO requests to a device. svctim average time (ms) a device was servicing requests. qutim = await ­ svctim 
  • qutim Czas który JVM traci na oczekiwanie na operacje IO
  • select() (POSIX) epoll() (Linux) kqueue (*BSD) /dev/poll
  • syscall requests a service from kernel userspace kernelspace CPU privileged mode glibc
  • sun.nio.ch.DefaultSelectorProvider if ("Linux".equals(osname)) { String osversion = AccessController.doPrivileged( new GetPropertyAction("os.version")); String[] vers = osversion.split("\\.", 0); if (vers.length >= 2) { try { int major = Integer.parseInt(vers[0]); int minor = Integer.parseInt(vers[1]); if (major > 2 || (major == 2 && minor >= 6)) { return new sun.nio.ch.EPollSelectorProvider(); } } catch (NumberFormatException x) { // format not recognized } } } return new sun.nio.ch.PollSelectorProvider();
  • java.nio Event loops Reactor pattern
  • Nie bądź głupi Użyj netty.io
  • Bufory IO pomiędzy kernel space I user space Operacje IO wymagają wielu operacji Kopiowania pomiędzy userspace i kernelspace DMA mmap() MMU
  • Here was slide about Memory mapped files & page faults, But somebody removed it :)
  • … and here was slide about Vectored IO But somebody else removed it :)
  • kernel-user space „zero copy” FileChannel#transferTo() wewnątrz JVM „zero copy” użyj Netty, serio CompositeByteBuf
  • Trade offs, stupid!
  • Blokować? Nie blokuj gdy, Dużo klientów masz Blokuj gdy, Strumienie przetwarzasz
  • CPUs and hard drives are really good at sequential reading/writing Use it
  • I grom potężny pazurem swym nieboskłon na strzępy rozdarł trzeci jeździec się wyłonił A imię jego
  • synchronized
  • Z pozoru wszystko wygląda niewinnie %system Context switches Voluntary (IO wait, syscall*) Non voluntary (within time slice) pidstat ­w ­t ­I ­p {pid} jstack {pid}
  • Waiting Is waste
  • Non blocking algorithms Wait-freedom Każda operacja zakończy się w z góry określonej ilości kroków/ instrukcji Lock-freedom Pozwala na zagłodzienie wybranych wątków, Przynajmniej jeden wątek wykonuje operacje Obstruction-freedom (optimistic concurrency)
  • Compare-and-swap java.util.concurrent.atomic „transakcyjne” metody Copy on write Persistent data structures
  • Atomic operations are getting faster and faster With every new CPU But we are not there yet!
  • I wody z oceanów wystąpiły, A z nich bestie żarłoczne, Człowiekowi nieprzychylne czwarty jeździec się wyłonił A imię jego
  • Just In Time compiler
  • Adaptive runtime Based on profiling data Slower startup times Slower peek peformance (in some cases*)
  • JIT (Just in Time) HotSpot Vs AOT (Ahead of Time) (www.excelsiorjet.com)
  • Interpreter C1 compiler C2 compiler OSR (on stack replacement) deoptimization
  • Inlining mother of all optimizations C1 compiler inlines small methods -XX:MaxInlineSize=35 -XX:InlineSmallCode=2000 C2 compiler inlines „hot” methods -XX:FreqInlineSize=325
  • public class Inline{ public int doubleAndSum(int x,y){ return makeDouble(x)+makeDouble(y); } private int makeDouble(int x){ return x+x; } //after inlining public int doubleAndSum(int x,y){ return (x+x)+(y+y); } }
  • The easy part private, static and final The hard part Polimorphism Class hierarchy analisys Deoptimization Beware of megamorph
  • const char* StackWalkCompPolicy::shouldInline(methodHandle m, float freq, int cnt) { // Allows targeted inlining // positive filter: should send be inlined? returns NULL (--> yes) // or rejection msg int max_size = MaxInlineSize; int cost = m->code_size(); // Check for too many throws (and not too huge) if (m->interpreter_throwout_count() > InlineThrowCount && cost < InlineThrowMaxSize ) { return NULL; } // bump the max size if the call is frequent if ((freq >= InlineFrequencyRatio) || (cnt >= InlineFrequencyCount)) { if (TraceFrequencyInlining) { tty->print("(Inlined frequent method)\n"); m->print(); } max_size = FreqInlineSize; } if (cost > max_size) { return (_msg = "too big"); } return NULL; }
  • Inline cache Inline depth Recursive inline
  • other optimizations remove redundant loads loop unrollling global value numbering intrinsic escape analisys
  • … And few others even more interesting lock elision lock coarsenning adaptive locking biased locking
  • But first few words about „fat” and „thin” locks
  • JVM uses futex A „mostly” userspace lock based on atomic value and wait queue Unless high contention which forces futex to use kernelspace mutex
  • WAT?
  • Daleko jeszcze?
  • What Every Programmer Should Know About Memory Cpu Caches and Why You Care Lock-Free Programming (or, Juggling Razor Blades) brain food for hackers Linux Device Drivers
  • Let the eternal stream of byte code Flows through your body
Fly UP