See More

# High Performance Java # ## The Course Overview ## 1. Java 9 performance enhancements 1. JShell 2. Writing good code in Java 9 2. Performance testing with JMH 1. Set up of benchmark suite 2. Constructing benchmark 3. Avoid dead code elimination in tests 4. Complex benchmarks 3. Compilers - Performance boosters 1. Just in time compilation 2. Ahead of time compilation 3. Segmented code cache 4. Summary of Java 9 performance improvement ## Performance Improvements ## 1. Topics 1. Java 9 performance improvements 2. Java 9 GC improvements 3. Jshell - Interactive console in Java 9 4. How to write good code in Java 9 - New Java 9 API 5. Better Java 9 string performance 6. Compact strings 7. Stored strings in the Class-Data Sharing (CDS) archives 8. Java concurrency - Reactive streams 2. Why strings are so important? 1. Most objects created by our programs are of string type 2. Java already optimize usage of string using string pool 1. Special memory region 1. There are shared strings new String("Cat"); // new object is created - anti-pattern 1. s1 == s2 (works if the string is in string pool) 3. Java 9 and class-data sharing (CDS) archives 1. Up to Java 8 string pool was per one per one JVM 2. In Java 9 string and char[] objects are shared between JVMs 3. It can reduce memory usage substantially 4. Compact strings 1. Up to Java 8, string was internally represented as char[] 2. In Java 9, XX:- CompactStrings compactions can be enabled 3. Using that flag, string is represented as byte[] (more effective because of size) 4. It improves space efficiency of string class 5. Reactive Streams 1. Java 9 adds reactive streams to the standard API 2. Publish-subscribe model 3. Flow Publisher extends Flow ## Java 9 GC Improvement ## 1. Topics 1. Java 9 change default garbage collection algorithm 1. First choice 2. Choosing G1 to be first choice 3. How G1 is working 4. Why it is a best general purpose GC 2. G1 Characteristics 1. Heap is divided into N equally sized regions 2. Max 2048 regions 3. Each region from 1 MB to 32 MB 4. Eden, survivor, and old generation can occupy every region 3. G1 Heap Allocation 1. Eden Space - young objects live here 2. Survivor space - all other objects live 3. Old generation - old objects 4. How young GC works in G1 1. End of young GC 1. Live objects from young generation have been evacuated (copied/moved) to 1. Zero or more survivor regions 2. Old generation regions 2. Ecend and survivor possibly resized 5. G1 Introduces Metaspace 1. Classes matadata and statics are stored in the native heap and this space is called Metaspace 1. GC cannot use native heap 2. By default metadata allocation is only limited by the amount of available native memory 1. Upto 3 GB (dangerous) - app may crash 3. Parameter `MaxMetaspaceSize` is used to set maximum amount of space 1. Native space is not exhausted 6. Garbage collection process 1. Object is in Eden (Young generation) 2. Object is moved to S0 - first pass if object survived (Young generation) 3. Object is moved to S1 - second pass if object survived (Young generation) 4. Object is moved to Tenured - third pass if object survived (Old Generation) 5. Permanent - Metaspace (JDK 1.8 and later) - separate space (not seen by GC) 1. Statics 2. Classes ## JShell - Interactive Console in Java 9 ## 1. Topics 1. Setup Java 9 2. Starting JShell 3. REPL (Read Evaluate Print Loop) - What it is? 4. Playing with Java code using JShell 1. Iteractive shell (without main method) 2. Steps: 1. Download JDK 9 1. [http://jdk.java.net/9/](http://jdk.java.net/9/) 2. `cd jdk-9/bin` 3. `jshell` 4. Example: List integers = new LinkedList<>() integers integers.add(1) (tab) temporary variable is created String a = "cat" String b = a integers.stream().filter(v -> v > 1).collect(Collectors.toList()) 1. We don't have to import anything CompletableFuture.supplyAsync(() -> "hello").get() ## How to Write Good Code in Java 9 ## 1. Topics 1. How Java 9 favors collections and immutability 2. Treating optional as stream of one or zero elements 3. Using dropWhile()/takeWhile() 4. Parallel Files.lines() that use MappedByteBuffer 2. Java 8 way: // given Set set = new HashSet<>(); set.add("a"); set.add("b"); set.add("c"); // when Set strings = Collections.unmodifiableSet(set); strings.add("a"); // Throws UnsupportedOperationException 3. Java 9 way: // given Set set = Set.of("a", "b", "c"); //when set.add("a"); // Throws UnsupportedOperationException 4. Map the Java 9 way: // given Map map = Map.of(k1: 1, v1: "a", k2: 2, v2: "b"); // when map.put(3, "a"); // Throws ... 1. Similarly `List.of` 5. Example: // given Optional value = Optional.of("a"); // when List collect = value.stream().map(String::toUpperCase).collect(Collectors.toList()); // then assertThat(collect).hasSameElementsAs(List.of("A")); 6. `takeWhile` in Stream API // given Stream integerStream = Stream.of(10, 5, 1); // when List collect = integerStream.sorted(Comparator.reverseOrder()) .takeWhile(v -> v > 1) // beware of ordering stream!! takeWhile only gives determistic .collect(Collectors.toList()); // then assertThat(collect).hasSameElementsAs(List.of(10, 5)); 1. `takeWhile`: as long as the condition is being met it continues but as soon as condition fails, it quits. The elements are processed from lowest index to highest index 2. `dropWhile`: as long as the condition is being met, the element is dropped. The elements are processed from lowest index to highest index // given Stream integerStream = Stream.of(1, 2, 3, 4, 5); // when List collect = integerStream .sorted() //.parallel() // don't use this .dropWhile(v -> v < 4) // beware of ordering stream!! .collect(Collectors.toList()); // then assertThat(collect).hasSameElementsAs(List.of(4, 5)); 7. Parallel Files.lines() that use MappedByteBuffer 1. Up to Java 8, lines were read using Spliterator that divide work non-evenly 1. Longest task took substantial amount of time, maling all parallel tasks waiting for its finish 2. In Java 9, it chunks an input into N MappedByteBuffer of same size making computation faster 8. Summary 1. Explored Java 9 performance improvements 2. Discussed Java 9 GC improvements 3. Explained JShell - Interactive REPL in Java 9 4. Constructed an efficient code using new Java 9 API ## Setup Benchmarks Suite ## 1. For high performance of application 2. Topics 1. Setup benchmarks suite 2. Constructing benchmarks with warm up period 3. Avoid dead code elimination in tests 4. Constructing complex benchmarks 3. Topics of this video 1. Constructing project with JMH 2. Looking at the pom.xml 3. Constructing simple test suite 4. Starting a performance test 4. Generating project mvn archetype:generate \ -DinteractiveMode=false \ -DarchetypeGroupId=org.openjdk.jmh \ -DarchetypeArtifactId=jmh-java-benchmark-archetype \ -DgroupId=com.tomekl007 \ -DartifactId=packt_jmh \ 1. To start benchmark java -jar target/benchmarks.jar ## Constructing Benchmarks with Warm up Period ## ## Avoid Dead Code Elimination in Tests ## ## Constructing Complex Benchmark ## ## Just-in-time Compilation ## ## Ahead of Time Compilation ## ## Segmented Code Cache ## # Writing High Performance Java application in Java 9 # ## The Course Overview ## ## Java Memory Model ## ## Hardware Affinity ## ## JVM Intrinsic Functions ## ## Understanding and Analyzing Bytecode ## ## Optimistic Locking Versus Pessimistic Locking ## ## CompareAndSet Structures ## ## Coordinating Threads ## ## Java 9 - Reactive Streams ## ## Detecting Memory Leaks - JVisualVM ## ## Examining CPU and Resources Usage ## ## Summary of Writing High Performance Java Applications ##