Wydajność w Java
Tworzenie wydajnych aplikacji w Java
Kod szkolenia: JAVA-WYD
Szkolenie jest adresowane do programistów języka Java, którzy chcą poznać sekrety tworzenia wydajnego oprogramowania w tym języku.
Celem szkolenia jest obycie się z praktykami tworzenia wydajnego oprogramowania w Java, poprzez tworzenie benchmark’ów i badanie wydajności, profilowanie aplikacji, używanie struktur danych odpowiednich do trybu pracy, wydajny dostęp do plików i przede wszystkim obalenie błędnych mitów dotyczących pracy Garbage Collector’a. Wielu programistów Java posiadających nawet wieloletnie doświadczenie nie zdaje sobie sprawy z tego jakie grzechy popełnia próbując pomagać wirtualnej maszynie Java, czy Garbage Collector’owi, w rezultacie otrzymując efekt przeciwny do zamierzonego. To szkolenie obala te mity i uczy prawdziwych praktyk tworzenia wydajnego oprogramowania w Javie. A także jak zwiększyć wydajność aplikacji bez dotykania samego kodu, czyli profilowanie JVM i GC.
5 dni, po 8 godzin. Łącznie 40 godzin(y) szkolenia.
Oczekiwane przygotowanie słuchaczy przed szkoleniem
Od uczestników wymagana jest umiejętność programowania w języku Java.
Polecane szkolenia uzupełniające
Szkolenie poprzedzające - Programowanie w Java (JAVA-PRO).
Inne szkolenia zaawansowane:
wielowątkowość (JAVA-WAT), projektowanie (JAVA-WZO), architektura (JAVA-ARCH)
- Tworzenie wydajnego oprogramowania
- Różne wymiary wydajności
- Wydajność obliczeniowa
- Wydajność pamięciowa (RAM footprint)
- Wydajność uruchomienia
- Wydajność skalowania
- Wydajność a użytkownik – subiektywne odczucie wydajności
- Proces tworzenia wydajnego oprogramowania
- Analiza wydajności
- Projektowanie a wydajność
- Architektura a wydajność
- Kodowanie a wydajność
- Testowanie a wydajność
- Profilowanie a wydajność
- Co wpływa na wydajność w Javie
- Pomiary wydajności
- Problemy ze zwiększaniem wydajności
- Co to jest Benchmarking
- Sposoby dokonywania pomiarów
- Zalety budowania benchmarków
- Micro-benchmark
- Macro-benchmark
- Problemy wyników pomiarowania
- Czym jest profilowanie aplikacji
- Wpływ profilowania na wydajność
- Problemy z płaskim profilowaniem
- Zalety narzędzi do profilowania
- Narzędzia do profilowania
- Problemy do zdiagnozowania
- Opis narzędzi
- Obsługa wybranych narzędzi
- JConsole
- Java VisualVM
- JMC (Java Mission Control)
- MAT (Memory Analyzer)
- Wydajna praca z plikami
- Strumienie
- Podstawy
- Analiza alternatywnych rozwiązań
- Porównania wydajności rozwiązań na strumieniach
- Swobodny dostęp do plików
- Lepsza wydajność – biblioteka NIO
- Kanały
- FileChannel
- ByteBuffer
- Przykłady użycia kanałów
- Porównanie wydajność rozwiązań
- Odwzorowywanie plików w pamięci
- Porównanie wydajności różnych metod dostępu do plików
- NIO2
- Path (operacje na ścieżkach)
- Files (operacje na plikach i katalogach)
- Kopiowanie/Przenoszenie
- System plików
- Nowe funkcje odczytu/zapisu
- StandardOpenOptions
- Nowa konstrukcja try i autocloseable (try-with-resources)
- Serializacja
- Podstawy serializacji
- Problemy z serializacją
- Analiza wyników serializacji
- Sposoby optymalizacji serializacji
- Algorytm wydajności
- Sztuka doboru algorytmu
- Porównanie algorytmów
- Elegancja a brute-force
- Dziedzina problemu a algorytm
- Problemy z rekurencją
- Nie tylko algorytm się liczy
- Kolekcje i tablice
- API kolekcji
- Podstawowe interfejsy
- Iterator<E>
- Iterable<E>
- Collection<E>
- Set<E>
- List<E>
- Queue<E>
- Deque<E>
- Map<K, V>
- Najważniejsze funkcje
- Struktury danych – podstawy wydajnych operacji
- Tablica haszująca
- Kontrakt między equals a hashCode
- Kontrakt equals
- Problemy z danymi w tablicy haszującej
- Przeszukiwanie binarne
- Drzewa czerwono-czarne
- Opis zagadnienia
- Zasady działania
- Przykłady działania
- Zbiory
- Wydajność standardowych implementacji
- HashSet<E>
- TreeSet<E>
- LinkedHashSet<E>
- EnumSet<E>
- Poszerzone interfejsy zbiorów
- NavigableSet<E>
- Optymalizacja pracy na zbiorach
- Porównanie wydajności różnych implementacji zbiorów
- Listy
- Wydajność standardowych implementacji
- ArrayList<E>
- LinkedList<E>
- Optymalizacja pracy z listami
- Porównanie wydajności list
- Opis struktur ArrayList i LinkedList
- Interfejs RandomAccess a wydajność przeglądania listy
- Kolejki
- Wydajność standardowych implementacji
- PriorityQueue<E>
- LinkedList<E>
- Kolejki dwustronne
- Interfejs Deque<E>
- Wydajność implementacji kolejki dwustronnej
- LinkedList<E>
- ArrayDeque<E>
- Mapy
- Wydajność standardowych implementacji
- HashMap<K,V>
- TreeMap<K,V>
- EnumMap<K,V>
- IdentityHashMap<K,V>
- WeakHashMap<K,V>
- LinkedHashMap<K,V>
- Poszerzone interfejsy map
- NavigableMap<K,V>
- Optymalizacja pracy na mapach
- Porównanie wydajności map
- Jak stworzyć cache
- Stare kontenery (Java 1.0 i 1.1)
- Implementacje starych kontenerów
- Hashtable<K,V>
- Vector<E>
- Stack<E>
- BitSet
- Enumerator – Enumeration<E>
- Porównanie wydajności z nowymi implementacjami
- Widok kolekcji
- Zalety używania
- Niebezpieczeństwa
- Optymalizacja
- Collections - klasa pomocnicza
- Podstawowe funkcje
- Rola w optymalizacji
- Wykorzystanie w algorytmach
- Wydajność a kolekcje odporne na wielowątkowość
- Wydajność kolejek wielowątkowych
- ConcurrentLinkedQueue<E>
- Wydajność kolejek blokujących
- BlockingQueue<E>
- ArrayBlockingQueue<E>
- TransferQueue<E>
- LinkedTransferQueue<E>
- DelayQueue<E extends Delayed>
- LinkedBlockingQueue<E>
- PriorityBlockingQueue<E>
- SynchronousQueue<E>
- Wydajność dwustronnych kolejek blokujących
- BlockingDeque<E>
- LinkedBlockingDeque<E>
- Wydajność list wielowątkowych
- CopyOnWriteArrayList<E>
- Wydajność map wielowątkowych
- ConcurrentMap<K,V>
- ConcurrentNavigableMap<K,V>
- ConcurrentHashMap<K,V>
- ConcurrentSkipListMap<K,V>
- Tablice
- Zalety stosowania tablic
- Wady stosowania tablic
- Porównanie tablic z ArrayList
- Klasa pomocnicza Arrays
- JMH – microbenchmak framework
- Czym jest JMH
- @Benchmark
- Przygotowanie projektu JMH
- Uruchomienie JMH
- Wyniki benchmarków
- Dodatkowa konfiguracja benchmarków
- @Warmup
- @Measurement
- @OutputTimeUnit
- @Timeout
- @OperationsPerInvocation
- @BenchmarkMode
- @Fork
- Współbieżność
- @Threads
- @Group
- @GroupThreads
- Benchmarki parametryzowalne
- @State(Scope)
- @Param
- @Setup i @Teardown
- Blackhole i bezpieczne pętle
- Pułapki
- Inne frameworki
- Informacje dodatkowe (opcjonalne)
- Więcej o grupach
- Więcej o Level.Invocation
- Profilery
- @CompilerControl
- @AuxCounters
- Co jeszcze można wstrzyknąć
- Zarządzanie pamięcią
- Java a zarządzanie pamięcią
- Jak działa odśmiecanie pamięci (Garbage Collector)
- Co gwarantuje Garbage Collector?
- Cykl życia obiektu
- Fazy cyklu życia obiektu
- Wyspy obiektów
- Metoda finalize
- Problemy i pułapki
- Typy referencji a Garbage Collector i proces odśmiecania
- SoftReference
- WeakReference
- PhantomReference
- Wycieki pamięci w Javie
- Powody
- Złe praktyki
- Unikanie
- Garbage Collector - złe praktyki
- Ograniczanie zajętości pamięci
- Opcje strojenia Garbage Collector’a
- Parametry konfiguracyjne Garbage Collector’a
- Słaba teoria generacji
- Typy odśmiecania
- Minor Collections
- Major Collections
- Generacje obiektów
- Organizacja pamięci w Javie
- Młoda generacja
- Eden
- Survivor Spaces
- Stara generacja
- Pamięć permanentna
- Opcje podglądu pracy GC
- Parametry wydajnościowe Garbage Collector
- Wymiarowanie pamięci (generacji)
- Optymalizacja algorytmu odśmiecania
- Rodzaje GC
- Rodzaje
- Serial Collector
- Parallel Collector
- Concurent Collector
- G1
- ZGC
- Epsilon
- Shenandoah
- Zasady działania
- Preferencje
- Skalowalność
- Strojenie
- Problemy i rozwiązania
- Zing jako alternatywa
- Zalecenia przy wyborze GC
- Inne opcje strojenia GC
- Maszyna wirtualna Javy
- Podstawowe tryby pracy a wydajność
- Parametry wydajnościowe JVM
- Przegląd wybranych macrobenchmarków
- JBB2015
- VolanoMark
- Usprawnienia w Java
- Problemy z optymalizacją
- Optymalizacje kompilatora a micro-benchmark
- Micro-benchmark a GC
- Uruchamianie wielu aplikacji
- Przyzwyczajenia programistów
- Optymalizacja za kompilator
- Przedwczesna optymalizacja
- Antywzorze związane z wydajnością
- Zachłanność
- Pośpiech
- Lenistwo
- Ignorancja