SlideShare a Scribd company logo
Java Keeps
Throttling Up!
Rémi ForaxRémi Forax
StarringStarring
José PaumardJosé Paumard
var local type var inference
10
var local type var inference
10
11 var as lambda parameters raw string nestmatescondy
inner classes
private in VM
11 var as lambda parameters nestmatescondy
inner classes
private in VM
12 expr switch
type switch record
const lambda
11 var as lambda parameters nestmatescondy
inner classes
private in VM
12 expr switch
type switch record
const lambda
13+
sealed interface
pattern matching
value type
raw string
Public Poll!
You can get Kahoot! to participate in the poll, just before
the coffee break
Les bons artistes copient,
les grands artistes volent
Chapter 1
Graal
Anatomy of a Java Distribution
Language Tools
– compiler: javac, ecj
– jshell, jlink, javadoc, javap, jdb, etc
Runtime Environment
– A class library: OpenJDK, Harmony (discontinuated)
– A virtual Machine: Hotspot, J9
●
Bytecode compiler: c1 / c2, graal (java), falcon (llvm)
●
Garbage collector: CMS / G1 / ZGC, shenandoah, c4
Graal
A Java bytecode compiler written in Java
JVM Compiler Interface (JEP 243)
– Interface between the VM and the bytecode compiler
– Hotspot and J9 support JVMCI (since Java 9)
But Graal recompiles itself at the same time it compiles the
application ?
Graal JIT + AOT
Two configurations
– Just in Time Compiler (like c1 and c2)
– Ahead of Time Compiler (like any C compilers)
Graal compiles itself ahead of time (since april 2019)
– libgraal (shared library)
– Clean separation of the memory resource
Trade off between JIT vs AOT
JIT knows runtime informations
– Exact CPU version
– Application Profiling (delayed JIT)
– Can not use slow optimizations
AOT knows all the codes
– Fast startup time, lower runtime overhead
– No dynamic support (no dynamic classloading, no bytecode generation)
– Can not use optimizations that generates too much assembly codes
What About the JIT Performances ?
Let us take a well-known benchmark:
The computation of the Mandelbrot set
Easy!
Julia Sets
Comes from the Julia set:
For a given value of c, this is the set of z0
For which zn+1 = zn
2 + c is bound
If |zn| becomes greater than 2
Then z0 does not belong to
the Julia set
Mandelbrot Set
Set of c for which
z0 = 0
zn+1 = zn
2 + c
Is bound
Computing the Mandelbrot Set
Make each point of an image a complex number c
Compute the following:
z0 = 0
zn+1 = zn
2 + c
If for some n, |zn| becomes greater than 2
Then c does not belong to the Mandelbrot set
Computing the Mandelbrot Set
Implementation: take an image of size 64x64
For each pixel z
If n reaches 1000 and |zn| stays lower than 2
Then the point belongs to the set
So there are about 16M multiplications to be made
All the multiplications are different
Computing the Mandelbrot Set
Complex provides a useful abstraction
for (var col = -32; col < +32; col++) {
for (var row = -32; row < +32; row++) {
var c = new Complex(col, row);
var zn = new Complex(0.0, 0.0);
var iteration = 0;
while (zn.modulus() < 4 && iteration < max) {
zn = zn.square().add(c);
iteration++;
}
if (iteration < max) {
image.setRGB(col, row, colors[iteration]);
} else {
image.setRGB(col, row, black);
}
}
}
Computing the Mandelbrot Set
Computing the Mandelbrot set C style
for (var col = -32; col < +32; col++) {
for (var row = -32; row < +32; row++) {
var an = 0.0; var bn = 0.0;
var iteration = 0;
while (an*an + bn*bn < 4 && iteration < max) {
var next_a = an*an - bn*bn + col;
var next_b = 2*an*bn + row;
an = next_a; bn = next_b;
iteration++;
}
if (iteration < max) {
image.setRGB(col, row, colors[iteration]);
} else {
image.setRGB(col, row, black);
}
}
}
JIT Performance with JMH
Time to render Mandelbrot 64x64
With jdk 11 (c1 + c2)
score error
primitive 1540 µs/op 22 µs/op
reference 2816 µs/op 48 µs/op
JIT Performance with JMH
Time to render Mandelbrot 64x64
libgraal (ce-rc15) -XX:+UseJVMCICompiler
score error
primitive 1544 µs/op 10 µs/op
reference 1542 µs/op 7 µs/op
GraalVM: a Java 8 Distribution
Language Tools
– compiler: javac, ecj
– jshell, jlink, javadoc, javap, jdb, native-image, etc
Runtime Environment
– A class library: OpenJDK + Truffle
– A virtual Machine: Hotspot
●
Bytecode compiler: c1 / c2, graal (java)
●
Garbage collector: CMS / G1 / ZGC
– A C backend optimizer: llvm
native-image
Precompile a JVM-based application into one executable
Use Graal AOT + SubstrateVM
SubstrateVM
– Low memory footprint VM
– No dynamic linking support
– Use low pause non generationnal GC
Support Java, Scala, Kotlin, Clojure
Truffle
Write an interpreter with some specialization machinery to help
the partial evaluator (Graal), get a compiler for free
Truffle is a Java library
– runs on Hotspot or Substrate VM
– ask Graal to aggressively optimize the code
– Allows (dynamic) languages interoperability at runtime
In a Nutshell
A Java 8 application can be executed on:
1) HotSpot with C1 / C2 as JIT compilers
2) HotSpot with Graal as JIT compiler
3) A Jlink generated JRE with HotSpot
4) A native image, AOT compiled with Graal,
executed on SubstrateVM
What Do You Need to Compare ?
How much time it takes to link the application ?
The size of the application ?
How fast does it execute ?
Link-time, run-time & storage
scan rt.jar and compute stats
link-time run-time storage
jdk11 - 1.70 s 288 k (304 M)
jdk8 + libgraal - 1.32 s 288 k (878 M)
jdk11 + jlink 2.2 s 1.53 s 43 M
native-image 22 s (43s) 0.79 s 10 M
OpenJDK Project Metropolis
Rewrite Hotspot in Java
Use libgraal as JIT to replace c1/c2
Rewrite the runtime in Java
Interpreter in Java ?
Rewrite the GCs in Java
Need a JVMGCI ?
Chapter 2
Valhalla
C’s Struct on stack
Stack allocation in C
C allows stack allocation
typedef struct _complex {
double re;
double im;
} complex;
complex c; // allocate re and im on stack
Abstraction with no allocation cost !
Aliasing and Stack
If structs are passed as pointers, the compiler doesn’t know
if it’s the same address is in memory or not
void foo(complex* c1, complex* c2) {
c1 -> re = 5;
// does c2 -> re has been changed or not ?
}
In Java, you can not create an address on stack
Because the VM re-arranges the stack frames at runtime
Value class
A simple immutable class tagged as value
public value class Complex {
private final double re;
private final double im;
public Complex(double re, double im) {
this.re = re;
this.im = im;
}
public Complex add(Complex c) {
return new Complex(re + c.re, im + c.im);
}
}
Value type
Immediate value with no header
– Immutable and final
– No identity (no address in heap)
– Non null
– Can implement interfaces
Motto: “Code like a class, works like an int”
Back to the Mandelbrot Set
Complex provides a useful abstraction
for (var col = -32; col < +32; col++) {
for (var row = -32; row < +32; row++) {
var c = new Complex(row, col);
var zn = new Complex(0.0, 0.0);
var iteration = 0;
while (zn.modulus() < 4 && iteration < max) {
zn = zn.square().add(c);
iteration++;
}
if (iteration < max) {
image.setRGB(col, row, colors[iteration]);
} else {
image.setRGB(col, row, black);
}
}
}
Demo Mandelbrot
JMH
How much time to render the Mandelbrot 64x64 with 1000
iterations?
With java -XX:+EnableValhalla
score error
primitive 1540 µs/op 22 µs/op
reference 2816 µs/op 48 µs/op
value 1541 µs/op 12 µs/op
Optional/Option
public value class Option<E> {
private final E value;
private Option(E value) {
this.value = value;
}
public static <E> Option<E> empty() {
return Option<E>.default;
}
public static <E> Option<E> of(E value) {
Objects.requireNonNull(value);
return new Option<>(value);
}
public static <E> Option<E> ofNullable(E value) {
return (value == null)? empty(): of(value);
}
...
All fields are 0, null, 0.0, etc
Demo Optional
Benchmark with JMH
private static final Map<String, Integer> MAP = Map.of("foo", 1, "bar", 2, "baz", 3);
private static final List<String> LIST = List.of("a", "foo", "b", "bar", "c", "baz");
@Benchmark
public int sum_null() {
int sum = 0;
for(var key: LIST) {
var value = MAP.get(key);
sum += (value != null)? value: 0;
}
return sum;
}
@Benchmark
public int sum_optional() {
int sum = 0;
for(var key: LIST) {
var value = Optional.ofNullable(MAP.get(key));
sum += value.orElse(0);
}
return sum;
}
Benchmark with JMH
public final class value Option<E> {
private final E value;
private Option(E e) {
this.e = e;
}
public Option<E> of(E e) {
Objects.requireNonNull(e);
return new Option<>(e);
}
public static <E> Option<E> empty() {
return Option<E>.default;
}
public static <E> Option<E> ofNullable(E value) {
return (value == null)? empty(): of(value);
}
/* rest of the class */
}
@Benchmark
public int sum_option() {
int sum = 0;
for(var key: LIST) {
var value = Option.ofNullable(MAP.get(key));
sum += value.orElse(0);
}
return sum;
}
JMH
Time to compute the sum
With java -XX:+EnableValhalla
score error
sum_null 60.9 ns/op 0.9 ns/op
sum_optional 71.6 ns/op 3.6 ns/op
sum_option 61.3 ns/op 0.4 ns/op
Classes are not immutable
Problem: a class is not truly immutable
– You can see the field being initialized in the constructor
Only initialize through static factory
– Add 2 new opcodes: default/with
– Let the compiler do the lifting
But not binary compatible => bridges ??
Constructor are static factory
public value class IntBox {
private final int value;
private IntBox(int value) {
this.value = value;
}
public int intValue() {
return value;
}
public static IntBox zero() {
return IntBox.default;
}
public static IntBox valueOf(int value) {
var box = IntBox.default;
box = __WithField(box.value, value);
return box;
}
} WithField allows to change one field
Flattenable
Storing a value type in a field or an array
– Less pointer chasing!
Problems
– with volatile field
●
don’t flatten if volatile
– When writing without synchronized or volatile
●
value type tearing :(
Array flattening ?
Array of value types are flattenable
– Don’t flatten if too big !
header header
header
header
header
An array of java.lang.Integer An array of IntBox
Demo Flattening
Benchmark
Sum of an array of value type
private static final IntBox[] ARRAY = new IntBox[100_000];
static {
range(0, ARRAY.length).forEach(i -> ARRAY[i] = IntBox.valueOf(i));
}
@Benchmark
public int sum_IntBox() {
var sum = 0;
for(var value : ARRAY) {
sum += value.intValue();
}
return sum;
}
JMH
Time to sum an array of 100 000 values
With java -XX:+EnableValhalla
score error
primitive (int) 27.1 µs/op 0.2 µs/op
reference (Integer) 60.7 µs/op 0.6 µs/op
Value (IntBox) 27.0 µs/op 0.1 µs/op
Benchmark
What if we shuffle the values ?
private static final IntBox[] ARRAY = new IntBox[100_000];
static {
range(0, ARRAY.length).forEach(i -> ARRAY[i] = IntBox.valueOf(i));
Collections.shuffle(Arrays.asList(ARRAY));
}
@Benchmark
public int sum_IntBox() {
var sum = 0;
for(var value : ARRAY) {
sum += value.intValue();
}
return sum;
}
JMH
Time to sum an array of 100 000 random values
With java -XX:+EnableValhalla
score error
primitive (int) 27.1 µs/op 0.2 µs/op
reference (Integer) 121.9 µs/op 5.1 µs/op
Value (IntBox) 27.0 µs/op 0.1 µs/op
First Prototype
Minimum Value Type
– Reference Object can be
unboxed to a value type
– Value type are not subtype of
Object
●
Need to box first
Second Prototype
L-World
– Subtypes of Object
doesn’t work exactly like an int
:(
Minimum Value Type
– Reference Object can be
unboxed to a value type
– Value type are not subtype of
Object
●
Need to box first
L-world issues
Operations that requires an object header
● synchronized throws IllegalStateMonitorException
●
==
– opt-in to component-wise comparison or
– always false
Arrays are covariant
●
Array access are polymorphic :(
– The JIT try to aggressively hoist the element check
L-world issues : Generics
Erased so no flattening
●
Reify generics over value types
A type parameter can be null
●
Need a nullable value type for old generics
Complex?, IntBox?
L-world Issues : Concurrency
Value types are subjects of tearing
public value class SecurityToken {
private final long id1, id2;
public SecurityToken(long id1, long id2) {
if (id1 != id2) throw new IllegalArgumentException();
...
}
public void check() {
if (id1 != id2) throw new IllegalStateException();
}
public static void main(String[] args) {
var tokens = new SecurityToken[1];
IntStream.range(0, 2).forEach(id -> {
new Thread(() -> {
for(;;) {
tokens[0].check();
tokens[0] = new SecurityToken(id, id);
}
}).start();
});
} }
Votation
inline class vs immediate class
Poll!
1. Inline class!
2. Immediate class!
public immediate class Complex { … }
public inline class Complex { … }
Coffee (or whatever)
Break!
Coffee (or whatever)
Break!
Chapter 3
Loom
Erlang’s actors
Erlang Actor
Scheduled by the Erlang VM (BEAM)
counter(Sum) ->
receive % wait for some message
{increment} ->
counter(Sum+1); % tail-call
{value} ->
io:format("~p~n", [Sum]);
end.
pid ! {increment}; % send a message to pid
Thread are heavyweight !
A Thread
– Share the same address space
– Lightweight Lock
●
no context switch
but
– Thread stack is pre-reserved (=> OOM if a lot of threads)
– Thread scheduling is done by the OS !
Concurrency models
continuation model
Memory
OS
VM
T1 T2 T3
lock
thread model
Memory
OS
VM
T1 T2
lock
C1 C2 C3
Continuation
Wrap a Runnable
Continuation.run() execute the runnable
– Can stop itself with a yield !
– A call to run() will restart the runnable
just after the yield
No language support needed
A simple example
Create a continuation and run it
var scope = new ContinuationScope("example");
var continuation = new Continuation(scope, () -> {
System.out.println("hello Devoxx France");
});
System.out.println("start continuation");
continuation.run();
A simple example
Create a continuation and call run(), yield(), run()
var scope = new ContinuationScope("example");
var continuation = new Continuation(scope, () -> {
System.out.println("hello Devoxx France");
Continuation.yield(scope);
System.out.println("i’m back !");
});
System.out.println("start continuation");
continuation.run();
System.out.println("restart continuation");
continuation.run();
How does it work ?
Yield copy the all stack frames on heap !
main
run
f1
f2
heap
run
f1
f2
How does it work ?
Then run() move some stack frames back
main
f2
heap
stack bang!
The VM tries to guess
how many stack frames
should be moved
A read of the stack bang
trigger the copy of the
remaining frames
Delimited Continuation vs Thread
Scheduling explicit (yield, run)
– No OS context switch
No heap reservation
– Only store what is actually needed !
Erlang Actor
Scheduled by the Erlang VM (BEAM)
counter(Sum) ->
receive % wait for some message
{increment} ->
counter(Sum+1); % tail-call
{value} ->
io:format("~p~n", [Sum]);
end.
pid ! {increment}; % send a message to pid
Java Actor ?
Scheduled by the JVM/JDK
var actor = new Actor(new Runnable() {
int sum;
public void run() {
while (true) {
receive(message -> { // wait for some message
switch((String)message {
case "increment" ->
sum++; // side effect
case "value" -> {
System.out.println(sum);
exit();
}
}});
}
}});
actor.send("increment"); // send a message to the actor
Demo Actor
Demo TCP Proxy
Fiber
Wrap a Runnable
Scheduled using an ExecutorService
– A fiber is scheduled on a thread
Blocking calls (read, write, sleep)
– Freeze the fiber, schedule another one
– Re-scheduled
●
When a read/write/locks/etc will not block
●
Maybe scheduled on another thread
Fiber vs Continuation
A fiber delegates the suspension (yield) to the continuation
– All blocking calls do internally a yield
– The JDK code calls run() on the continuation
when it can be rescheduled
All the JDK needs to be patched to be “fiber aware”
Fiber/Continuation limitation
Continuation/Fiber
– Can not yield if there is a native frame on the stack
Fiber
– Yielding inside a synchronized block pins the fiber to that thread
●
The same thread as to be used when re-scheduling
●
This limitation may be removed in the future
Thread related API ?
Some Thread related APIs need to be reworked
Thread.currentThread()
– Need to lazily create a fake thread per fiber :(
ThreadLocal/InheritableThreadLocal
– Redirect thread local to fiber locals
Will consume a lot of memory
Roadmap
Tailcall support ?
– Not implemented yet
Performance ?
– Still a prototype !
No version of Java targeted, yet !
Chapter 4
Amber
Groovy’s smart-cast
Precise type inference
Groovy (with @CompileStatic) change the type of a variable after
an instanceof
Object x = ...
if (x instanceof String) {
print(x.length()); // x is a String here !
}
// x is not a String here !
Instanceof in Java
Extends the intanceof syntax to define a new variable
Object x = ...
if (x instanceof String s) {
System.out.println(s.length());
}
Avoid to introduce an intersection type
if (x instanceof I || x instanceof J) { … }
Declaration/Definition
The rules for declaration/definition are a little surprising
class Point {
private final int x;
private final int y;
…
@Override
public boolean equals(Object o) {
if (!(o instanceof Point p) {
return false;
}
return x == p.x && y == p.y;
}
...
}
declaration
definition
Declaration/Definition
Other examples
if (x instanceof String s && s.length() == 3) { …
if (x instanceof String s || foo()) { /* no s here */ }
(x instanceof String s)? s.length(): /* no s here */
while(x instanceof String s) {
… s.length()
}
Enhanced instanceof
Not yet scheduled for a peculiar
version of Java
Kotlin’s Data Class
Data storage class
Sometimes a class is just a storage for data
In Java, you get encapsulation by default,
So you need to declare fields, write boring constructors, boring getters,
boring equals, hashCode and toString
While in Kotlin
you have data class
data class User(val name: String, val age: Int)
the compiler generates
constructor, getters/setters, equals(), hashCode() and
toString()
Known problems
Data class in Kotlin
Can be mutable
So storing data class is a HashSet/HashMap
is a mess
You can still declare fields
There are not used in equals/hashCode/toString ??
The boilerplate code is still there on disk
Record in Java
record User(String name, int age)
A record (a data carrier)
is non mutable
generates overridable
●
Constructor, accessors: String name(), int age()
●
equals/hashCode/toString
– Implementation is provided by invokedynamic
has no supplementary fields
An example
The primary constructor can specify pre-conditions
public record User(String name, int age) {
public User {
Objects.requireNonNull(name);
}
public boolean isOld() {
return age > 14;
}
}
Record vs other features
A record can be combined with a value type
value record User(String name, int age)
the keyword “value” acts as a modifier
Records will have a special support for pattern matching
(using extractors)
Haskell’s Pattern Matching
Abstract data type in Haskell
A function is defined as a list of pattern matchs
data Expr = Value Int | Add Expr Expr
eval :: Expr -> Int
eval (Value v) = v
eval (Add l r) = eval(l) + eval(r)
Rough translation in Java
New features: sealed interface + switch expression
sealed interface Expr {
record Value(int v) implements Expr;
record Add(Expr l, Expr r) implements Expr;
}
int eval(Expr expr) {
return switch(expr) {
case Value(var v) -> v;
case Add(var l, var r) -> eval(l) + eval(r);
};
}
Demo !
What’s wrong with switch ?
String[] tokens = ...
Vehicle vehicle;
switch(tokens[0]) {
case "car":
case "sedan":
var color = tokens[1];
vehicle = new Car(color);
break;
case "bus":
vehicle = new Bus("yellow");
break;
default:
throw new …
}
What’s wrong with switch ?
String[] tokens = ...
Vehicle vehicle;
switch(tokens[0]) {
case "car":
case "sedan":
var color = tokens[1];
vehicle = new Car(color);
break;
case "bus":
vehicle = new Bus("yellow");
break;
default:
throw new …
}
fallthrough
weird scope
initialization hidden
Fix the switch
Separate the cases with a comma + arrow syntax
String[] tokens = ...
Vehicle vehicle;
switch(tokens[0]) {
case "car", "sedan" -> {
var color = tokens[1];
vehicle = new Car(color);
}
case "bus" -> {
vehicle = new Bus("yellow");
}
default -> throw new …
}
Add a switch expression
A switch that can “return” a value
var tokens = ...
var vehicle = switch(tokens[0]) {
case "car", "sedan" -> {
var color = tokens[1];
...
}
case "bus" -> new Bus("yellow");
default -> throw new …
};
Exhaustive Switch
The switch expression requires a “default”
var tokens = ...
var vehicle = switch(tokens[0]) {
case "car", "sedan" -> {
var color = tokens[1];
...
}
case "bus" -> new Bus("yellow");
default -> throw new …
};
Exhaustive Switch (again)
For enums, default is not required if exhaustive
enum Kind { CAR, SEDAN, BUS }
var tokens = ...
var vehicle = switch(kind) {
case CAR, SEDAN -> {
var color = tokens[1];
...
}
case BUS -> new Bus("yellow");
};
Return a value from a block
And not return from the method
var tokens = ...
var vehicle = switch(tokens[0]) {
case "car", "sedan" -> {
var color = tokens[1];
??? new Car(color);
}
case "bus" -> new Bus("yellow");
default -> throw new …
};
Return a value from a block
And not return from the method
var tokens = ...
var vehicle = switch(tokens[0]) {
case "car", "sedan" -> {
var color = tokens[1];
break new Car(color);
}
case "bus" -> new Bus("yellow");
default -> throw new …
};
Hyphen keyword
Using ‘-’ to extend the number of keywords !
var tokens = ...
var vehicle = switch(tokens[0]) {
case "car", "sedan" -> {
var color = tokens[1];
break-with new Car(color);
}
case "bus" -> new Bus("yellow");
default -> throw new …
};
Switch enhancement
Retrofit old switch
– Arrow syntax and comma separated case values work for both switch
Introduce switch expression
– exhaustive
– default not needed for enums
Switch enhancement
Already in Java 12
– Under the flag --enable-preview
Not a preview feature in Java 13
– Uses break-with instead of break
LISP’s macro
String concatenation
A simple benchmark
class PerfTest {
static int value = 4;
@Benchmark
public String test_concat() {
return "err: " + value + " !";
}
@Benchmark
public String test_builder() {
return new StringBuilder().append("err: ")
.append(value).append(" !").toString();
}
@Benchmark
public String test_format() {
return String.format("err: %d !", value);
}
}
JMH
With Java 11
String.format() is super slow !
score error
test_concat 0.013 µs/op 0.001 µs/op
test_builder 0.014 µs/op 0.001 µs/op
test_format 0.502 µs/op 0.034 µs/op
Generated bytecodes
The format parsing is super slow + boxing/varargs
public static java.lang.String format(int);
0: ldc #10 // String err: %d !
2: iconst_1
3: anewarray #11 // class java/lang/Object
6: dup
7: iconst_0
8: iload_0
9: invokestatic #12 // Integer.valueOf:(I)LInteger;
12: aastore
13: invokestatic #13 // String.format:(LString;[LObject;)LString;
16: areturn
JMH
With amber-compiler intrinsics
it’s not slow anymore !
score error
test_concat 0.014 µs/op 0.001 µs/op
test_builder 0.014 µs/op 0.001 µs/op
test_format 0.014 µs/op 0.001 µs/op
Amber / intrinsics
The compiler uses invokedynamic instead
public static java.lang.String format(int);
0: iload_0
1: invokedynamic #10, 0 // #1:format:(I)LString;
6: areturn
bootstraps
1: #35 invokeStatic IntrinsicFactory.staticStringFormatBootstrap
(LLookup;LString;LmethodType;LString;)LCallSite;
Method arguments:
#36 err: %d !
Limitations
Only works if
– the format is a constant!
– the format has no dependency on java.util.Locale!
(double formatting)
In the work
– should work for JIT constant not only compiler constant
– Consider the Locale as a constant + deoptimisation
Scala’s Lazy constant
Example in Java
Java class initialization is lazy by default
=> so not issue here!
But static block initialization is the devil
Usually trigger other class initializations
=> applications are slooow to boot
Use Scala’s lazy keyword
class Utils {
public static final lazy Path HOME =
Path.of(System.getenv("HOME"));
}
Problem:
Scala uses the Double-checked Locking pattern
The Double-checked Pattern
The correct implementation disables further useful optimizations :(
class Utils {
private static volatile Path HOME;
public static Path getHome() {
var home = HOME; // volatile read
if (home == null) {
synchronized(Utils.class) {
home = HOME;
if (home == null) {
return HOME = Path.of(System.getenv("HOME"));
}
}
}
return home;
}
}
Constant Pool
A classfile has a dictionnary of all constants (constant pool), each
constant is transformed once to a runtime Java Object
#30: ...
#31: Utf8: "hello riviera dev"
#32: String: #31
#33: ...
class Utils {
public static void main(String[] args) {
//System.out.println("hello riviera dev");
ldc #32
...
}
}
Constant Dynamic
ConstandDynamic (Java 11) is a constant that can be computed dynamically
#28: Utf8: "Ljava/nio/file/Path;"
#29: Utf8: "HOME"
#30: NameAndType: #29:#28 // HOME Ljava/nio/file/Path;
#31: MethodHandle 6:#… // Utils.lazy_HOME_init ()Ljava/nio/file/Path;
#32: ConstantDynamic: 00:#30
BootstrapMethods:
00: #31
class Utils {
private static Path lazy_HOME_init() { return Path.of(System.getenv("HOME")); }
public static void main(String[] args) {
//System.out.println(??);
ldc #32
...
}
}
Demo !
Compilation Strategies
A lazy static field
Loaded from the same class
●
Use ldc
Loaded from another class
●
Use getstatic ?
getstatic
Opcode getstatic need to be changed to recognize attribute DynamicValue
#30: NameAndType: #29:#28 // HOME Ljava/nio/file/Path;
#31: MethodHandle 6:#… // Utils.lazy_HOME_init ()Ljava/nio/file/Path;
#32: ConstantDynamic: 00:#30
#33: Field …:#30 // Utils.HOME Ljava/nio/file/Path;
BootstrapMethods:
00: #31
class Utils {
field: #30
DynamicValue: #32
private static Path lazy_HOME_init() { return Path.of(System.getenv("HOME")); }
public static void main(String[] args) {
//System.out.println(??);
getstatic #33
...
}
}
Lazy static : Java vs Scala
Scala (double-checked pattern)
– Guarantee singleton
– Perf issue: Volatile read + nullcheck
Java (getstatic + constant dynamic)
– Singleton after creation
●
need to be idempotent
– Plain static final read
●
constant for the VM
Lazy static final in Java
Scheduled to be introduced in Java 14
“lazy” can not be used on final instance field
C#’s raw string
Example in Java
Embedded code is unreadable
var html =
"<html>n" +
" <body style="width: 100vw">n" +
" <p>Hello World.</p>n" +
" </body>n" +
" <script>console.log("loadedn")</script>n" +
"</html>";
Example in Java
Embedded code has a lot of boilerplate
var html =
"<html>n" +
" <body style="width: 100vw">n" +
" <p>Hello World.</p>n" +
" </body>n" +
" <script>console.log("loadedn")</script>n" +
"</html>";
Borrow C# raw string
var html =
@"<html>
<body style=""width: 100vw"">
<p>Hello World.</p>
</body>
<script>console.log(""loadedn"")</script>
</html>";
but with a different delimiter
– C# needs to de-specialized quotes
– we can not embed C# easily in Java
Proposed Solution – Fat String
Use """ to start and end a fat strings
var html =
"""<html>
<body style="width: 100vw">
<p>Hello World.</p>
</body>
<script>console.log("loadedn")</script>
</html>""";
Examples
With pattern matching
var pattern = Pattern.compile("""""");
A multi-lines string
var s = """this is a long
multi-lines
of text""";
Embedded code
var s = """< a href="javascript: alert('hello')">""";
Fat/Raw String in Java
Was initially scheduled for Java 11
Was a real raw String (no escape of u….)
Using a variable number of backticks (`)
But early adopter reactions were “meeh”
Still in discussion
Raw ? Auto-alignment ?
That’s it!
Questions??

More Related Content

What's hot

Deep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UKDeep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UK
José Paumard
 
Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1
José Paumard
 
Sneaking inside Kotlin features
Sneaking inside Kotlin featuresSneaking inside Kotlin features
Sneaking inside Kotlin features
Chandra Sekhar Nayak
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
Mario Fusco
 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMMario Fusco
 
Kotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime PerformanceKotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime Performance
intelliyole
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of Flattery
José Paumard
 
Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardMario Fusco
 
Why we cannot ignore Functional Programming
Why we cannot ignore Functional ProgrammingWhy we cannot ignore Functional Programming
Why we cannot ignore Functional ProgrammingMario Fusco
 
Java Class Design
Java Class DesignJava Class Design
Java Class Design
Ganesh Samarthyam
 
Kotlin advanced - language reference for android developers
Kotlin advanced - language reference for android developersKotlin advanced - language reference for android developers
Kotlin advanced - language reference for android developers
Bartosz Kosarzycki
 
Rust Workshop - NITC FOSSMEET 2017
Rust Workshop - NITC FOSSMEET 2017 Rust Workshop - NITC FOSSMEET 2017
Rust Workshop - NITC FOSSMEET 2017
pramode_ce
 
Kotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projectsKotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projects
Bartosz Kosarzycki
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
HamletDRC
 
Advanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesAdvanced Debugging Using Java Bytecodes
Advanced Debugging Using Java Bytecodes
Ganesh Samarthyam
 
Kotlin as a Better Java
Kotlin as a Better JavaKotlin as a Better Java
Kotlin as a Better Java
Garth Gilmour
 
Programming in Scala: Notes
Programming in Scala: NotesProgramming in Scala: Notes
Programming in Scala: Notes
Roberto Casadei
 
Practical Functional Programming Presentation by Bogdan Hodorog
Practical Functional Programming Presentation by Bogdan HodorogPractical Functional Programming Presentation by Bogdan Hodorog
Practical Functional Programming Presentation by Bogdan Hodorog
3Pillar Global
 

What's hot (19)

Deep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UKDeep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UK
 
Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1
 
Sneaking inside Kotlin features
Sneaking inside Kotlin featuresSneaking inside Kotlin features
Sneaking inside Kotlin features
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
 
Kotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime PerformanceKotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime Performance
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of Flattery
 
Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forward
 
Why we cannot ignore Functional Programming
Why we cannot ignore Functional ProgrammingWhy we cannot ignore Functional Programming
Why we cannot ignore Functional Programming
 
Java Class Design
Java Class DesignJava Class Design
Java Class Design
 
Kotlin advanced - language reference for android developers
Kotlin advanced - language reference for android developersKotlin advanced - language reference for android developers
Kotlin advanced - language reference for android developers
 
Rust Workshop - NITC FOSSMEET 2017
Rust Workshop - NITC FOSSMEET 2017 Rust Workshop - NITC FOSSMEET 2017
Rust Workshop - NITC FOSSMEET 2017
 
Kotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projectsKotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projects
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
 
Advanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesAdvanced Debugging Using Java Bytecodes
Advanced Debugging Using Java Bytecodes
 
Monadic Java
Monadic JavaMonadic Java
Monadic Java
 
Kotlin as a Better Java
Kotlin as a Better JavaKotlin as a Better Java
Kotlin as a Better Java
 
Programming in Scala: Notes
Programming in Scala: NotesProgramming in Scala: Notes
Programming in Scala: Notes
 
Practical Functional Programming Presentation by Bogdan Hodorog
Practical Functional Programming Presentation by Bogdan HodorogPractical Functional Programming Presentation by Bogdan Hodorog
Practical Functional Programming Presentation by Bogdan Hodorog
 

Similar to Java Keeps Throttling Up!

Scala to assembly
Scala to assemblyScala to assembly
Scala to assembly
Jarek Ratajski
 
Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
JAXLondon_Conference
 
Design Patterns - Compiler Case Study - Hands-on Examples
Design Patterns - Compiler Case Study - Hands-on ExamplesDesign Patterns - Compiler Case Study - Hands-on Examples
Design Patterns - Compiler Case Study - Hands-on Examples
Ganesh Samarthyam
 
12 Monkeys Inside JS Engine
12 Monkeys Inside JS Engine12 Monkeys Inside JS Engine
12 Monkeys Inside JS Engine
ChengHui Weng
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
Doug Hawkins
 
Java 5 6 Generics, Concurrency, Garbage Collection, Tuning
Java 5 6 Generics, Concurrency, Garbage Collection, TuningJava 5 6 Generics, Concurrency, Garbage Collection, Tuning
Java 5 6 Generics, Concurrency, Garbage Collection, TuningCarol McDonald
 
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
PVS-Studio
 
How to add an optimization for C# to RyuJIT
How to add an optimization for C# to RyuJITHow to add an optimization for C# to RyuJIT
How to add an optimization for C# to RyuJIT
Egor Bogatov
 
NVIDIA HPC ソフトウエア斜め読み
NVIDIA HPC ソフトウエア斜め読みNVIDIA HPC ソフトウエア斜め読み
NVIDIA HPC ソフトウエア斜め読み
NVIDIA Japan
 
Devnology Workshop Genpro 2 feb 2011
Devnology Workshop Genpro 2 feb 2011Devnology Workshop Genpro 2 feb 2011
Devnology Workshop Genpro 2 feb 2011Devnology
 
00_Introduction to Java.ppt
00_Introduction to Java.ppt00_Introduction to Java.ppt
00_Introduction to Java.ppt
HongAnhNguyn285885
 
The Effect of Hierarchical Memory on the Design of Parallel Algorithms and th...
The Effect of Hierarchical Memory on the Design of Parallel Algorithms and th...The Effect of Hierarchical Memory on the Design of Parallel Algorithms and th...
The Effect of Hierarchical Memory on the Design of Parallel Algorithms and th...
David Walker
 
Cross Platform App Development with C++
Cross Platform App Development with C++Cross Platform App Development with C++
Cross Platform App Development with C++
Joan Puig Sanz
 
Pointcuts and Analysis
Pointcuts and AnalysisPointcuts and Analysis
Pointcuts and AnalysisWiwat Ruengmee
 
Building High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low EffortBuilding High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low Effort
Stefan Marr
 
Deuce STM - CMP'09
Deuce STM - CMP'09Deuce STM - CMP'09
Deuce STM - CMP'09
Guy Korland
 
How do you create a programming language for the JVM?
How do you create a programming language for the JVM?How do you create a programming language for the JVM?
How do you create a programming language for the JVM?
Federico Tomassetti
 
Building Efficient and Highly Run-Time Adaptable Virtual Machines
Building Efficient and Highly Run-Time Adaptable Virtual MachinesBuilding Efficient and Highly Run-Time Adaptable Virtual Machines
Building Efficient and Highly Run-Time Adaptable Virtual Machines
Guido Chari
 
C++11: Feel the New Language
C++11: Feel the New LanguageC++11: Feel the New Language
C++11: Feel the New Languagemspline
 

Similar to Java Keeps Throttling Up! (20)

Scala to assembly
Scala to assemblyScala to assembly
Scala to assembly
 
Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
 
Design Patterns - Compiler Case Study - Hands-on Examples
Design Patterns - Compiler Case Study - Hands-on ExamplesDesign Patterns - Compiler Case Study - Hands-on Examples
Design Patterns - Compiler Case Study - Hands-on Examples
 
12 Monkeys Inside JS Engine
12 Monkeys Inside JS Engine12 Monkeys Inside JS Engine
12 Monkeys Inside JS Engine
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
 
Java 5 6 Generics, Concurrency, Garbage Collection, Tuning
Java 5 6 Generics, Concurrency, Garbage Collection, TuningJava 5 6 Generics, Concurrency, Garbage Collection, Tuning
Java 5 6 Generics, Concurrency, Garbage Collection, Tuning
 
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
 
Why MacRuby Matters
Why MacRuby MattersWhy MacRuby Matters
Why MacRuby Matters
 
How to add an optimization for C# to RyuJIT
How to add an optimization for C# to RyuJITHow to add an optimization for C# to RyuJIT
How to add an optimization for C# to RyuJIT
 
NVIDIA HPC ソフトウエア斜め読み
NVIDIA HPC ソフトウエア斜め読みNVIDIA HPC ソフトウエア斜め読み
NVIDIA HPC ソフトウエア斜め読み
 
Devnology Workshop Genpro 2 feb 2011
Devnology Workshop Genpro 2 feb 2011Devnology Workshop Genpro 2 feb 2011
Devnology Workshop Genpro 2 feb 2011
 
00_Introduction to Java.ppt
00_Introduction to Java.ppt00_Introduction to Java.ppt
00_Introduction to Java.ppt
 
The Effect of Hierarchical Memory on the Design of Parallel Algorithms and th...
The Effect of Hierarchical Memory on the Design of Parallel Algorithms and th...The Effect of Hierarchical Memory on the Design of Parallel Algorithms and th...
The Effect of Hierarchical Memory on the Design of Parallel Algorithms and th...
 
Cross Platform App Development with C++
Cross Platform App Development with C++Cross Platform App Development with C++
Cross Platform App Development with C++
 
Pointcuts and Analysis
Pointcuts and AnalysisPointcuts and Analysis
Pointcuts and Analysis
 
Building High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low EffortBuilding High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low Effort
 
Deuce STM - CMP'09
Deuce STM - CMP'09Deuce STM - CMP'09
Deuce STM - CMP'09
 
How do you create a programming language for the JVM?
How do you create a programming language for the JVM?How do you create a programming language for the JVM?
How do you create a programming language for the JVM?
 
Building Efficient and Highly Run-Time Adaptable Virtual Machines
Building Efficient and Highly Run-Time Adaptable Virtual MachinesBuilding Efficient and Highly Run-Time Adaptable Virtual Machines
Building Efficient and Highly Run-Time Adaptable Virtual Machines
 
C++11: Feel the New Language
C++11: Feel the New LanguageC++11: Feel the New Language
C++11: Feel the New Language
 

More from José Paumard

Loom Virtual Threads in the JDK 19
Loom Virtual Threads in the JDK 19Loom Virtual Threads in the JDK 19
Loom Virtual Threads in the JDK 19
José Paumard
 
From Java 11 to 17 and beyond.pdf
From Java 11 to 17 and beyond.pdfFrom Java 11 to 17 and beyond.pdf
From Java 11 to 17 and beyond.pdf
José Paumard
 
The Future of Java: Records, Sealed Classes and Pattern Matching
The Future of Java: Records, Sealed Classes and Pattern MatchingThe Future of Java: Records, Sealed Classes and Pattern Matching
The Future of Java: Records, Sealed Classes and Pattern Matching
José Paumard
 
Designing functional and fluent API: application to some GoF patterns
Designing functional and fluent API: application to some GoF patternsDesigning functional and fluent API: application to some GoF patterns
Designing functional and fluent API: application to some GoF patterns
José Paumard
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of Flattery
José Paumard
 
Designing functional and fluent API: example of the Visitor Pattern
Designing functional and fluent API: example of the Visitor PatternDesigning functional and fluent API: example of the Visitor Pattern
Designing functional and fluent API: example of the Visitor Pattern
José Paumard
 
Construire son JDK en 10 étapes
Construire son JDK en 10 étapesConstruire son JDK en 10 étapes
Construire son JDK en 10 étapes
José Paumard
 
Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2
José Paumard
 
Asynchronous Systems with Fn Flow
Asynchronous Systems with Fn FlowAsynchronous Systems with Fn Flow
Asynchronous Systems with Fn Flow
José Paumard
 
JAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) BridgeJAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) Bridge
José Paumard
 
Collectors in the Wild
Collectors in the WildCollectors in the Wild
Collectors in the Wild
José Paumard
 
Streams in the wild
Streams in the wildStreams in the wild
Streams in the wild
José Paumard
 
JAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridgeJAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridge
José Paumard
 
Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
José Paumard
 
L'API Collector dans tous ses états
L'API Collector dans tous ses étatsL'API Collector dans tous ses états
L'API Collector dans tous ses états
José Paumard
 
Linked to ArrayList: the full story
Linked to ArrayList: the full storyLinked to ArrayList: the full story
Linked to ArrayList: the full story
José Paumard
 
Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
José Paumard
 
ArrayList et LinkedList sont dans un bateau
ArrayList et LinkedList sont dans un bateauArrayList et LinkedList sont dans un bateau
ArrayList et LinkedList sont dans un bateau
José Paumard
 
Java SE 8 for Java EE developers
Java SE 8 for Java EE developersJava SE 8 for Java EE developers
Java SE 8 for Java EE developers
José Paumard
 
Asynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFutureAsynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFuture
José Paumard
 

More from José Paumard (20)

Loom Virtual Threads in the JDK 19
Loom Virtual Threads in the JDK 19Loom Virtual Threads in the JDK 19
Loom Virtual Threads in the JDK 19
 
From Java 11 to 17 and beyond.pdf
From Java 11 to 17 and beyond.pdfFrom Java 11 to 17 and beyond.pdf
From Java 11 to 17 and beyond.pdf
 
The Future of Java: Records, Sealed Classes and Pattern Matching
The Future of Java: Records, Sealed Classes and Pattern MatchingThe Future of Java: Records, Sealed Classes and Pattern Matching
The Future of Java: Records, Sealed Classes and Pattern Matching
 
Designing functional and fluent API: application to some GoF patterns
Designing functional and fluent API: application to some GoF patternsDesigning functional and fluent API: application to some GoF patterns
Designing functional and fluent API: application to some GoF patterns
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of Flattery
 
Designing functional and fluent API: example of the Visitor Pattern
Designing functional and fluent API: example of the Visitor PatternDesigning functional and fluent API: example of the Visitor Pattern
Designing functional and fluent API: example of the Visitor Pattern
 
Construire son JDK en 10 étapes
Construire son JDK en 10 étapesConstruire son JDK en 10 étapes
Construire son JDK en 10 étapes
 
Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2
 
Asynchronous Systems with Fn Flow
Asynchronous Systems with Fn FlowAsynchronous Systems with Fn Flow
Asynchronous Systems with Fn Flow
 
JAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) BridgeJAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) Bridge
 
Collectors in the Wild
Collectors in the WildCollectors in the Wild
Collectors in the Wild
 
Streams in the wild
Streams in the wildStreams in the wild
Streams in the wild
 
JAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridgeJAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridge
 
Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
 
L'API Collector dans tous ses états
L'API Collector dans tous ses étatsL'API Collector dans tous ses états
L'API Collector dans tous ses états
 
Linked to ArrayList: the full story
Linked to ArrayList: the full storyLinked to ArrayList: the full story
Linked to ArrayList: the full story
 
Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
 
ArrayList et LinkedList sont dans un bateau
ArrayList et LinkedList sont dans un bateauArrayList et LinkedList sont dans un bateau
ArrayList et LinkedList sont dans un bateau
 
Java SE 8 for Java EE developers
Java SE 8 for Java EE developersJava SE 8 for Java EE developers
Java SE 8 for Java EE developers
 
Asynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFutureAsynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFuture
 

Recently uploaded

Synthetic Fiber Construction in lab .pptx
Synthetic Fiber Construction in lab .pptxSynthetic Fiber Construction in lab .pptx
Synthetic Fiber Construction in lab .pptx
Pavel ( NSTU)
 
Chapter 3 - Islamic Banking Products and Services.pptx
Chapter 3 - Islamic Banking Products and Services.pptxChapter 3 - Islamic Banking Products and Services.pptx
Chapter 3 - Islamic Banking Products and Services.pptx
Mohd Adib Abd Muin, Senior Lecturer at Universiti Utara Malaysia
 
1.4 modern child centered education - mahatma gandhi-2.pptx
1.4 modern child centered education - mahatma gandhi-2.pptx1.4 modern child centered education - mahatma gandhi-2.pptx
1.4 modern child centered education - mahatma gandhi-2.pptx
JosvitaDsouza2
 
Digital Artifact 2 - Investigating Pavilion Designs
Digital Artifact 2 - Investigating Pavilion DesignsDigital Artifact 2 - Investigating Pavilion Designs
Digital Artifact 2 - Investigating Pavilion Designs
chanes7
 
Best Digital Marketing Institute In NOIDA
Best Digital Marketing Institute In NOIDABest Digital Marketing Institute In NOIDA
Best Digital Marketing Institute In NOIDA
deeptiverma2406
 
Multithreading_in_C++ - std::thread, race condition
Multithreading_in_C++ - std::thread, race conditionMultithreading_in_C++ - std::thread, race condition
Multithreading_in_C++ - std::thread, race condition
Mohammed Sikander
 
Operation Blue Star - Saka Neela Tara
Operation Blue Star   -  Saka Neela TaraOperation Blue Star   -  Saka Neela Tara
Operation Blue Star - Saka Neela Tara
Balvir Singh
 
Chapter 4 - Islamic Financial Institutions in Malaysia.pptx
Chapter 4 - Islamic Financial Institutions in Malaysia.pptxChapter 4 - Islamic Financial Institutions in Malaysia.pptx
Chapter 4 - Islamic Financial Institutions in Malaysia.pptx
Mohd Adib Abd Muin, Senior Lecturer at Universiti Utara Malaysia
 
A Strategic Approach: GenAI in Education
A Strategic Approach: GenAI in EducationA Strategic Approach: GenAI in Education
A Strategic Approach: GenAI in Education
Peter Windle
 
Mule 4.6 & Java 17 Upgrade | MuleSoft Mysore Meetup #46
Mule 4.6 & Java 17 Upgrade | MuleSoft Mysore Meetup #46Mule 4.6 & Java 17 Upgrade | MuleSoft Mysore Meetup #46
Mule 4.6 & Java 17 Upgrade | MuleSoft Mysore Meetup #46
MysoreMuleSoftMeetup
 
Unit 8 - Information and Communication Technology (Paper I).pdf
Unit 8 - Information and Communication Technology (Paper I).pdfUnit 8 - Information and Communication Technology (Paper I).pdf
Unit 8 - Information and Communication Technology (Paper I).pdf
Thiyagu K
 
The Challenger.pdf DNHS Official Publication
The Challenger.pdf DNHS Official PublicationThe Challenger.pdf DNHS Official Publication
The Challenger.pdf DNHS Official Publication
Delapenabediema
 
Introduction to AI for Nonprofits with Tapp Network
Introduction to AI for Nonprofits with Tapp NetworkIntroduction to AI for Nonprofits with Tapp Network
Introduction to AI for Nonprofits with Tapp Network
TechSoup
 
"Protectable subject matters, Protection in biotechnology, Protection of othe...
"Protectable subject matters, Protection in biotechnology, Protection of othe..."Protectable subject matters, Protection in biotechnology, Protection of othe...
"Protectable subject matters, Protection in biotechnology, Protection of othe...
SACHIN R KONDAGURI
 
Biological Screening of Herbal Drugs in detailed.
Biological Screening of Herbal Drugs in detailed.Biological Screening of Herbal Drugs in detailed.
Biological Screening of Herbal Drugs in detailed.
Ashokrao Mane college of Pharmacy Peth-Vadgaon
 
Advantages and Disadvantages of CMS from an SEO Perspective
Advantages and Disadvantages of CMS from an SEO PerspectiveAdvantages and Disadvantages of CMS from an SEO Perspective
Advantages and Disadvantages of CMS from an SEO Perspective
Krisztián Száraz
 
Francesca Gottschalk - How can education support child empowerment.pptx
Francesca Gottschalk - How can education support child empowerment.pptxFrancesca Gottschalk - How can education support child empowerment.pptx
Francesca Gottschalk - How can education support child empowerment.pptx
EduSkills OECD
 
2024.06.01 Introducing a competency framework for languag learning materials ...
2024.06.01 Introducing a competency framework for languag learning materials ...2024.06.01 Introducing a competency framework for languag learning materials ...
2024.06.01 Introducing a competency framework for languag learning materials ...
Sandy Millin
 
S1-Introduction-Biopesticides in ICM.pptx
S1-Introduction-Biopesticides in ICM.pptxS1-Introduction-Biopesticides in ICM.pptx
S1-Introduction-Biopesticides in ICM.pptx
tarandeep35
 
STRAND 3 HYGIENIC PRACTICES.pptx GRADE 7 CBC
STRAND 3 HYGIENIC PRACTICES.pptx GRADE 7 CBCSTRAND 3 HYGIENIC PRACTICES.pptx GRADE 7 CBC
STRAND 3 HYGIENIC PRACTICES.pptx GRADE 7 CBC
kimdan468
 

Recently uploaded (20)

Synthetic Fiber Construction in lab .pptx
Synthetic Fiber Construction in lab .pptxSynthetic Fiber Construction in lab .pptx
Synthetic Fiber Construction in lab .pptx
 
Chapter 3 - Islamic Banking Products and Services.pptx
Chapter 3 - Islamic Banking Products and Services.pptxChapter 3 - Islamic Banking Products and Services.pptx
Chapter 3 - Islamic Banking Products and Services.pptx
 
1.4 modern child centered education - mahatma gandhi-2.pptx
1.4 modern child centered education - mahatma gandhi-2.pptx1.4 modern child centered education - mahatma gandhi-2.pptx
1.4 modern child centered education - mahatma gandhi-2.pptx
 
Digital Artifact 2 - Investigating Pavilion Designs
Digital Artifact 2 - Investigating Pavilion DesignsDigital Artifact 2 - Investigating Pavilion Designs
Digital Artifact 2 - Investigating Pavilion Designs
 
Best Digital Marketing Institute In NOIDA
Best Digital Marketing Institute In NOIDABest Digital Marketing Institute In NOIDA
Best Digital Marketing Institute In NOIDA
 
Multithreading_in_C++ - std::thread, race condition
Multithreading_in_C++ - std::thread, race conditionMultithreading_in_C++ - std::thread, race condition
Multithreading_in_C++ - std::thread, race condition
 
Operation Blue Star - Saka Neela Tara
Operation Blue Star   -  Saka Neela TaraOperation Blue Star   -  Saka Neela Tara
Operation Blue Star - Saka Neela Tara
 
Chapter 4 - Islamic Financial Institutions in Malaysia.pptx
Chapter 4 - Islamic Financial Institutions in Malaysia.pptxChapter 4 - Islamic Financial Institutions in Malaysia.pptx
Chapter 4 - Islamic Financial Institutions in Malaysia.pptx
 
A Strategic Approach: GenAI in Education
A Strategic Approach: GenAI in EducationA Strategic Approach: GenAI in Education
A Strategic Approach: GenAI in Education
 
Mule 4.6 & Java 17 Upgrade | MuleSoft Mysore Meetup #46
Mule 4.6 & Java 17 Upgrade | MuleSoft Mysore Meetup #46Mule 4.6 & Java 17 Upgrade | MuleSoft Mysore Meetup #46
Mule 4.6 & Java 17 Upgrade | MuleSoft Mysore Meetup #46
 
Unit 8 - Information and Communication Technology (Paper I).pdf
Unit 8 - Information and Communication Technology (Paper I).pdfUnit 8 - Information and Communication Technology (Paper I).pdf
Unit 8 - Information and Communication Technology (Paper I).pdf
 
The Challenger.pdf DNHS Official Publication
The Challenger.pdf DNHS Official PublicationThe Challenger.pdf DNHS Official Publication
The Challenger.pdf DNHS Official Publication
 
Introduction to AI for Nonprofits with Tapp Network
Introduction to AI for Nonprofits with Tapp NetworkIntroduction to AI for Nonprofits with Tapp Network
Introduction to AI for Nonprofits with Tapp Network
 
"Protectable subject matters, Protection in biotechnology, Protection of othe...
"Protectable subject matters, Protection in biotechnology, Protection of othe..."Protectable subject matters, Protection in biotechnology, Protection of othe...
"Protectable subject matters, Protection in biotechnology, Protection of othe...
 
Biological Screening of Herbal Drugs in detailed.
Biological Screening of Herbal Drugs in detailed.Biological Screening of Herbal Drugs in detailed.
Biological Screening of Herbal Drugs in detailed.
 
Advantages and Disadvantages of CMS from an SEO Perspective
Advantages and Disadvantages of CMS from an SEO PerspectiveAdvantages and Disadvantages of CMS from an SEO Perspective
Advantages and Disadvantages of CMS from an SEO Perspective
 
Francesca Gottschalk - How can education support child empowerment.pptx
Francesca Gottschalk - How can education support child empowerment.pptxFrancesca Gottschalk - How can education support child empowerment.pptx
Francesca Gottschalk - How can education support child empowerment.pptx
 
2024.06.01 Introducing a competency framework for languag learning materials ...
2024.06.01 Introducing a competency framework for languag learning materials ...2024.06.01 Introducing a competency framework for languag learning materials ...
2024.06.01 Introducing a competency framework for languag learning materials ...
 
S1-Introduction-Biopesticides in ICM.pptx
S1-Introduction-Biopesticides in ICM.pptxS1-Introduction-Biopesticides in ICM.pptx
S1-Introduction-Biopesticides in ICM.pptx
 
STRAND 3 HYGIENIC PRACTICES.pptx GRADE 7 CBC
STRAND 3 HYGIENIC PRACTICES.pptx GRADE 7 CBCSTRAND 3 HYGIENIC PRACTICES.pptx GRADE 7 CBC
STRAND 3 HYGIENIC PRACTICES.pptx GRADE 7 CBC
 

Java Keeps Throttling Up!

  • 3.
  • 4. var local type var inference 10
  • 5. var local type var inference 10 11 var as lambda parameters raw string nestmatescondy inner classes private in VM
  • 6. 11 var as lambda parameters nestmatescondy inner classes private in VM 12 expr switch type switch record const lambda
  • 7. 11 var as lambda parameters nestmatescondy inner classes private in VM 12 expr switch type switch record const lambda 13+ sealed interface pattern matching value type raw string
  • 8. Public Poll! You can get Kahoot! to participate in the poll, just before the coffee break
  • 9. Les bons artistes copient, les grands artistes volent
  • 11. Anatomy of a Java Distribution Language Tools – compiler: javac, ecj – jshell, jlink, javadoc, javap, jdb, etc Runtime Environment – A class library: OpenJDK, Harmony (discontinuated) – A virtual Machine: Hotspot, J9 ● Bytecode compiler: c1 / c2, graal (java), falcon (llvm) ● Garbage collector: CMS / G1 / ZGC, shenandoah, c4
  • 12. Graal A Java bytecode compiler written in Java JVM Compiler Interface (JEP 243) – Interface between the VM and the bytecode compiler – Hotspot and J9 support JVMCI (since Java 9) But Graal recompiles itself at the same time it compiles the application ?
  • 13. Graal JIT + AOT Two configurations – Just in Time Compiler (like c1 and c2) – Ahead of Time Compiler (like any C compilers) Graal compiles itself ahead of time (since april 2019) – libgraal (shared library) – Clean separation of the memory resource
  • 14. Trade off between JIT vs AOT JIT knows runtime informations – Exact CPU version – Application Profiling (delayed JIT) – Can not use slow optimizations AOT knows all the codes – Fast startup time, lower runtime overhead – No dynamic support (no dynamic classloading, no bytecode generation) – Can not use optimizations that generates too much assembly codes
  • 15. What About the JIT Performances ? Let us take a well-known benchmark: The computation of the Mandelbrot set Easy!
  • 16. Julia Sets Comes from the Julia set: For a given value of c, this is the set of z0 For which zn+1 = zn 2 + c is bound If |zn| becomes greater than 2 Then z0 does not belong to the Julia set
  • 17. Mandelbrot Set Set of c for which z0 = 0 zn+1 = zn 2 + c Is bound
  • 18. Computing the Mandelbrot Set Make each point of an image a complex number c Compute the following: z0 = 0 zn+1 = zn 2 + c If for some n, |zn| becomes greater than 2 Then c does not belong to the Mandelbrot set
  • 19. Computing the Mandelbrot Set Implementation: take an image of size 64x64 For each pixel z If n reaches 1000 and |zn| stays lower than 2 Then the point belongs to the set So there are about 16M multiplications to be made All the multiplications are different
  • 20. Computing the Mandelbrot Set Complex provides a useful abstraction for (var col = -32; col < +32; col++) { for (var row = -32; row < +32; row++) { var c = new Complex(col, row); var zn = new Complex(0.0, 0.0); var iteration = 0; while (zn.modulus() < 4 && iteration < max) { zn = zn.square().add(c); iteration++; } if (iteration < max) { image.setRGB(col, row, colors[iteration]); } else { image.setRGB(col, row, black); } } }
  • 21. Computing the Mandelbrot Set Computing the Mandelbrot set C style for (var col = -32; col < +32; col++) { for (var row = -32; row < +32; row++) { var an = 0.0; var bn = 0.0; var iteration = 0; while (an*an + bn*bn < 4 && iteration < max) { var next_a = an*an - bn*bn + col; var next_b = 2*an*bn + row; an = next_a; bn = next_b; iteration++; } if (iteration < max) { image.setRGB(col, row, colors[iteration]); } else { image.setRGB(col, row, black); } } }
  • 22. JIT Performance with JMH Time to render Mandelbrot 64x64 With jdk 11 (c1 + c2) score error primitive 1540 µs/op 22 µs/op reference 2816 µs/op 48 µs/op
  • 23. JIT Performance with JMH Time to render Mandelbrot 64x64 libgraal (ce-rc15) -XX:+UseJVMCICompiler score error primitive 1544 µs/op 10 µs/op reference 1542 µs/op 7 µs/op
  • 24. GraalVM: a Java 8 Distribution Language Tools – compiler: javac, ecj – jshell, jlink, javadoc, javap, jdb, native-image, etc Runtime Environment – A class library: OpenJDK + Truffle – A virtual Machine: Hotspot ● Bytecode compiler: c1 / c2, graal (java) ● Garbage collector: CMS / G1 / ZGC – A C backend optimizer: llvm
  • 25. native-image Precompile a JVM-based application into one executable Use Graal AOT + SubstrateVM SubstrateVM – Low memory footprint VM – No dynamic linking support – Use low pause non generationnal GC Support Java, Scala, Kotlin, Clojure
  • 26. Truffle Write an interpreter with some specialization machinery to help the partial evaluator (Graal), get a compiler for free Truffle is a Java library – runs on Hotspot or Substrate VM – ask Graal to aggressively optimize the code – Allows (dynamic) languages interoperability at runtime
  • 27. In a Nutshell A Java 8 application can be executed on: 1) HotSpot with C1 / C2 as JIT compilers 2) HotSpot with Graal as JIT compiler 3) A Jlink generated JRE with HotSpot 4) A native image, AOT compiled with Graal, executed on SubstrateVM
  • 28. What Do You Need to Compare ? How much time it takes to link the application ? The size of the application ? How fast does it execute ?
  • 29. Link-time, run-time & storage scan rt.jar and compute stats link-time run-time storage jdk11 - 1.70 s 288 k (304 M) jdk8 + libgraal - 1.32 s 288 k (878 M) jdk11 + jlink 2.2 s 1.53 s 43 M native-image 22 s (43s) 0.79 s 10 M
  • 30. OpenJDK Project Metropolis Rewrite Hotspot in Java Use libgraal as JIT to replace c1/c2 Rewrite the runtime in Java Interpreter in Java ? Rewrite the GCs in Java Need a JVMGCI ?
  • 33. Stack allocation in C C allows stack allocation typedef struct _complex { double re; double im; } complex; complex c; // allocate re and im on stack Abstraction with no allocation cost !
  • 34. Aliasing and Stack If structs are passed as pointers, the compiler doesn’t know if it’s the same address is in memory or not void foo(complex* c1, complex* c2) { c1 -> re = 5; // does c2 -> re has been changed or not ? } In Java, you can not create an address on stack Because the VM re-arranges the stack frames at runtime
  • 35. Value class A simple immutable class tagged as value public value class Complex { private final double re; private final double im; public Complex(double re, double im) { this.re = re; this.im = im; } public Complex add(Complex c) { return new Complex(re + c.re, im + c.im); } }
  • 36. Value type Immediate value with no header – Immutable and final – No identity (no address in heap) – Non null – Can implement interfaces Motto: “Code like a class, works like an int”
  • 37. Back to the Mandelbrot Set Complex provides a useful abstraction for (var col = -32; col < +32; col++) { for (var row = -32; row < +32; row++) { var c = new Complex(row, col); var zn = new Complex(0.0, 0.0); var iteration = 0; while (zn.modulus() < 4 && iteration < max) { zn = zn.square().add(c); iteration++; } if (iteration < max) { image.setRGB(col, row, colors[iteration]); } else { image.setRGB(col, row, black); } } }
  • 39. JMH How much time to render the Mandelbrot 64x64 with 1000 iterations? With java -XX:+EnableValhalla score error primitive 1540 µs/op 22 µs/op reference 2816 µs/op 48 µs/op value 1541 µs/op 12 µs/op
  • 40. Optional/Option public value class Option<E> { private final E value; private Option(E value) { this.value = value; } public static <E> Option<E> empty() { return Option<E>.default; } public static <E> Option<E> of(E value) { Objects.requireNonNull(value); return new Option<>(value); } public static <E> Option<E> ofNullable(E value) { return (value == null)? empty(): of(value); } ... All fields are 0, null, 0.0, etc
  • 42. Benchmark with JMH private static final Map<String, Integer> MAP = Map.of("foo", 1, "bar", 2, "baz", 3); private static final List<String> LIST = List.of("a", "foo", "b", "bar", "c", "baz"); @Benchmark public int sum_null() { int sum = 0; for(var key: LIST) { var value = MAP.get(key); sum += (value != null)? value: 0; } return sum; } @Benchmark public int sum_optional() { int sum = 0; for(var key: LIST) { var value = Optional.ofNullable(MAP.get(key)); sum += value.orElse(0); } return sum; }
  • 43. Benchmark with JMH public final class value Option<E> { private final E value; private Option(E e) { this.e = e; } public Option<E> of(E e) { Objects.requireNonNull(e); return new Option<>(e); } public static <E> Option<E> empty() { return Option<E>.default; } public static <E> Option<E> ofNullable(E value) { return (value == null)? empty(): of(value); } /* rest of the class */ } @Benchmark public int sum_option() { int sum = 0; for(var key: LIST) { var value = Option.ofNullable(MAP.get(key)); sum += value.orElse(0); } return sum; }
  • 44. JMH Time to compute the sum With java -XX:+EnableValhalla score error sum_null 60.9 ns/op 0.9 ns/op sum_optional 71.6 ns/op 3.6 ns/op sum_option 61.3 ns/op 0.4 ns/op
  • 45. Classes are not immutable Problem: a class is not truly immutable – You can see the field being initialized in the constructor Only initialize through static factory – Add 2 new opcodes: default/with – Let the compiler do the lifting But not binary compatible => bridges ??
  • 46. Constructor are static factory public value class IntBox { private final int value; private IntBox(int value) { this.value = value; } public int intValue() { return value; } public static IntBox zero() { return IntBox.default; } public static IntBox valueOf(int value) { var box = IntBox.default; box = __WithField(box.value, value); return box; } } WithField allows to change one field
  • 47. Flattenable Storing a value type in a field or an array – Less pointer chasing! Problems – with volatile field ● don’t flatten if volatile – When writing without synchronized or volatile ● value type tearing :(
  • 48. Array flattening ? Array of value types are flattenable – Don’t flatten if too big ! header header header header header An array of java.lang.Integer An array of IntBox
  • 50. Benchmark Sum of an array of value type private static final IntBox[] ARRAY = new IntBox[100_000]; static { range(0, ARRAY.length).forEach(i -> ARRAY[i] = IntBox.valueOf(i)); } @Benchmark public int sum_IntBox() { var sum = 0; for(var value : ARRAY) { sum += value.intValue(); } return sum; }
  • 51. JMH Time to sum an array of 100 000 values With java -XX:+EnableValhalla score error primitive (int) 27.1 µs/op 0.2 µs/op reference (Integer) 60.7 µs/op 0.6 µs/op Value (IntBox) 27.0 µs/op 0.1 µs/op
  • 52. Benchmark What if we shuffle the values ? private static final IntBox[] ARRAY = new IntBox[100_000]; static { range(0, ARRAY.length).forEach(i -> ARRAY[i] = IntBox.valueOf(i)); Collections.shuffle(Arrays.asList(ARRAY)); } @Benchmark public int sum_IntBox() { var sum = 0; for(var value : ARRAY) { sum += value.intValue(); } return sum; }
  • 53. JMH Time to sum an array of 100 000 random values With java -XX:+EnableValhalla score error primitive (int) 27.1 µs/op 0.2 µs/op reference (Integer) 121.9 µs/op 5.1 µs/op Value (IntBox) 27.0 µs/op 0.1 µs/op
  • 54. First Prototype Minimum Value Type – Reference Object can be unboxed to a value type – Value type are not subtype of Object ● Need to box first
  • 55. Second Prototype L-World – Subtypes of Object doesn’t work exactly like an int :( Minimum Value Type – Reference Object can be unboxed to a value type – Value type are not subtype of Object ● Need to box first
  • 56. L-world issues Operations that requires an object header ● synchronized throws IllegalStateMonitorException ● == – opt-in to component-wise comparison or – always false Arrays are covariant ● Array access are polymorphic :( – The JIT try to aggressively hoist the element check
  • 57. L-world issues : Generics Erased so no flattening ● Reify generics over value types A type parameter can be null ● Need a nullable value type for old generics Complex?, IntBox?
  • 58. L-world Issues : Concurrency Value types are subjects of tearing public value class SecurityToken { private final long id1, id2; public SecurityToken(long id1, long id2) { if (id1 != id2) throw new IllegalArgumentException(); ... } public void check() { if (id1 != id2) throw new IllegalStateException(); } public static void main(String[] args) { var tokens = new SecurityToken[1]; IntStream.range(0, 2).forEach(id -> { new Thread(() -> { for(;;) { tokens[0].check(); tokens[0] = new SecurityToken(id, id); } }).start(); }); } }
  • 59. Votation inline class vs immediate class
  • 60. Poll! 1. Inline class! 2. Immediate class! public immediate class Complex { … } public inline class Complex { … }
  • 61. Coffee (or whatever) Break! Coffee (or whatever) Break!
  • 64. Erlang Actor Scheduled by the Erlang VM (BEAM) counter(Sum) -> receive % wait for some message {increment} -> counter(Sum+1); % tail-call {value} -> io:format("~p~n", [Sum]); end. pid ! {increment}; % send a message to pid
  • 65. Thread are heavyweight ! A Thread – Share the same address space – Lightweight Lock ● no context switch but – Thread stack is pre-reserved (=> OOM if a lot of threads) – Thread scheduling is done by the OS !
  • 66. Concurrency models continuation model Memory OS VM T1 T2 T3 lock thread model Memory OS VM T1 T2 lock C1 C2 C3
  • 67. Continuation Wrap a Runnable Continuation.run() execute the runnable – Can stop itself with a yield ! – A call to run() will restart the runnable just after the yield No language support needed
  • 68. A simple example Create a continuation and run it var scope = new ContinuationScope("example"); var continuation = new Continuation(scope, () -> { System.out.println("hello Devoxx France"); }); System.out.println("start continuation"); continuation.run();
  • 69. A simple example Create a continuation and call run(), yield(), run() var scope = new ContinuationScope("example"); var continuation = new Continuation(scope, () -> { System.out.println("hello Devoxx France"); Continuation.yield(scope); System.out.println("i’m back !"); }); System.out.println("start continuation"); continuation.run(); System.out.println("restart continuation"); continuation.run();
  • 70. How does it work ? Yield copy the all stack frames on heap ! main run f1 f2 heap run f1 f2
  • 71. How does it work ? Then run() move some stack frames back main f2 heap stack bang! The VM tries to guess how many stack frames should be moved A read of the stack bang trigger the copy of the remaining frames
  • 72. Delimited Continuation vs Thread Scheduling explicit (yield, run) – No OS context switch No heap reservation – Only store what is actually needed !
  • 73. Erlang Actor Scheduled by the Erlang VM (BEAM) counter(Sum) -> receive % wait for some message {increment} -> counter(Sum+1); % tail-call {value} -> io:format("~p~n", [Sum]); end. pid ! {increment}; % send a message to pid
  • 74. Java Actor ? Scheduled by the JVM/JDK var actor = new Actor(new Runnable() { int sum; public void run() { while (true) { receive(message -> { // wait for some message switch((String)message { case "increment" -> sum++; // side effect case "value" -> { System.out.println(sum); exit(); } }}); } }}); actor.send("increment"); // send a message to the actor
  • 77. Fiber Wrap a Runnable Scheduled using an ExecutorService – A fiber is scheduled on a thread Blocking calls (read, write, sleep) – Freeze the fiber, schedule another one – Re-scheduled ● When a read/write/locks/etc will not block ● Maybe scheduled on another thread
  • 78. Fiber vs Continuation A fiber delegates the suspension (yield) to the continuation – All blocking calls do internally a yield – The JDK code calls run() on the continuation when it can be rescheduled All the JDK needs to be patched to be “fiber aware”
  • 79. Fiber/Continuation limitation Continuation/Fiber – Can not yield if there is a native frame on the stack Fiber – Yielding inside a synchronized block pins the fiber to that thread ● The same thread as to be used when re-scheduling ● This limitation may be removed in the future
  • 80. Thread related API ? Some Thread related APIs need to be reworked Thread.currentThread() – Need to lazily create a fake thread per fiber :( ThreadLocal/InheritableThreadLocal – Redirect thread local to fiber locals Will consume a lot of memory
  • 81. Roadmap Tailcall support ? – Not implemented yet Performance ? – Still a prototype ! No version of Java targeted, yet !
  • 84. Precise type inference Groovy (with @CompileStatic) change the type of a variable after an instanceof Object x = ... if (x instanceof String) { print(x.length()); // x is a String here ! } // x is not a String here !
  • 85. Instanceof in Java Extends the intanceof syntax to define a new variable Object x = ... if (x instanceof String s) { System.out.println(s.length()); } Avoid to introduce an intersection type if (x instanceof I || x instanceof J) { … }
  • 86. Declaration/Definition The rules for declaration/definition are a little surprising class Point { private final int x; private final int y; … @Override public boolean equals(Object o) { if (!(o instanceof Point p) { return false; } return x == p.x && y == p.y; } ... } declaration definition
  • 87. Declaration/Definition Other examples if (x instanceof String s && s.length() == 3) { … if (x instanceof String s || foo()) { /* no s here */ } (x instanceof String s)? s.length(): /* no s here */ while(x instanceof String s) { … s.length() }
  • 88. Enhanced instanceof Not yet scheduled for a peculiar version of Java
  • 90. Data storage class Sometimes a class is just a storage for data In Java, you get encapsulation by default, So you need to declare fields, write boring constructors, boring getters, boring equals, hashCode and toString
  • 91. While in Kotlin you have data class data class User(val name: String, val age: Int) the compiler generates constructor, getters/setters, equals(), hashCode() and toString()
  • 92. Known problems Data class in Kotlin Can be mutable So storing data class is a HashSet/HashMap is a mess You can still declare fields There are not used in equals/hashCode/toString ?? The boilerplate code is still there on disk
  • 93. Record in Java record User(String name, int age) A record (a data carrier) is non mutable generates overridable ● Constructor, accessors: String name(), int age() ● equals/hashCode/toString – Implementation is provided by invokedynamic has no supplementary fields
  • 94. An example The primary constructor can specify pre-conditions public record User(String name, int age) { public User { Objects.requireNonNull(name); } public boolean isOld() { return age > 14; } }
  • 95. Record vs other features A record can be combined with a value type value record User(String name, int age) the keyword “value” acts as a modifier Records will have a special support for pattern matching (using extractors)
  • 97. Abstract data type in Haskell A function is defined as a list of pattern matchs data Expr = Value Int | Add Expr Expr eval :: Expr -> Int eval (Value v) = v eval (Add l r) = eval(l) + eval(r)
  • 98. Rough translation in Java New features: sealed interface + switch expression sealed interface Expr { record Value(int v) implements Expr; record Add(Expr l, Expr r) implements Expr; } int eval(Expr expr) { return switch(expr) { case Value(var v) -> v; case Add(var l, var r) -> eval(l) + eval(r); }; }
  • 100. What’s wrong with switch ? String[] tokens = ... Vehicle vehicle; switch(tokens[0]) { case "car": case "sedan": var color = tokens[1]; vehicle = new Car(color); break; case "bus": vehicle = new Bus("yellow"); break; default: throw new … }
  • 101. What’s wrong with switch ? String[] tokens = ... Vehicle vehicle; switch(tokens[0]) { case "car": case "sedan": var color = tokens[1]; vehicle = new Car(color); break; case "bus": vehicle = new Bus("yellow"); break; default: throw new … } fallthrough weird scope initialization hidden
  • 102. Fix the switch Separate the cases with a comma + arrow syntax String[] tokens = ... Vehicle vehicle; switch(tokens[0]) { case "car", "sedan" -> { var color = tokens[1]; vehicle = new Car(color); } case "bus" -> { vehicle = new Bus("yellow"); } default -> throw new … }
  • 103. Add a switch expression A switch that can “return” a value var tokens = ... var vehicle = switch(tokens[0]) { case "car", "sedan" -> { var color = tokens[1]; ... } case "bus" -> new Bus("yellow"); default -> throw new … };
  • 104. Exhaustive Switch The switch expression requires a “default” var tokens = ... var vehicle = switch(tokens[0]) { case "car", "sedan" -> { var color = tokens[1]; ... } case "bus" -> new Bus("yellow"); default -> throw new … };
  • 105. Exhaustive Switch (again) For enums, default is not required if exhaustive enum Kind { CAR, SEDAN, BUS } var tokens = ... var vehicle = switch(kind) { case CAR, SEDAN -> { var color = tokens[1]; ... } case BUS -> new Bus("yellow"); };
  • 106. Return a value from a block And not return from the method var tokens = ... var vehicle = switch(tokens[0]) { case "car", "sedan" -> { var color = tokens[1]; ??? new Car(color); } case "bus" -> new Bus("yellow"); default -> throw new … };
  • 107. Return a value from a block And not return from the method var tokens = ... var vehicle = switch(tokens[0]) { case "car", "sedan" -> { var color = tokens[1]; break new Car(color); } case "bus" -> new Bus("yellow"); default -> throw new … };
  • 108. Hyphen keyword Using ‘-’ to extend the number of keywords ! var tokens = ... var vehicle = switch(tokens[0]) { case "car", "sedan" -> { var color = tokens[1]; break-with new Car(color); } case "bus" -> new Bus("yellow"); default -> throw new … };
  • 109. Switch enhancement Retrofit old switch – Arrow syntax and comma separated case values work for both switch Introduce switch expression – exhaustive – default not needed for enums
  • 110. Switch enhancement Already in Java 12 – Under the flag --enable-preview Not a preview feature in Java 13 – Uses break-with instead of break
  • 112. String concatenation A simple benchmark class PerfTest { static int value = 4; @Benchmark public String test_concat() { return "err: " + value + " !"; } @Benchmark public String test_builder() { return new StringBuilder().append("err: ") .append(value).append(" !").toString(); } @Benchmark public String test_format() { return String.format("err: %d !", value); } }
  • 113. JMH With Java 11 String.format() is super slow ! score error test_concat 0.013 µs/op 0.001 µs/op test_builder 0.014 µs/op 0.001 µs/op test_format 0.502 µs/op 0.034 µs/op
  • 114. Generated bytecodes The format parsing is super slow + boxing/varargs public static java.lang.String format(int); 0: ldc #10 // String err: %d ! 2: iconst_1 3: anewarray #11 // class java/lang/Object 6: dup 7: iconst_0 8: iload_0 9: invokestatic #12 // Integer.valueOf:(I)LInteger; 12: aastore 13: invokestatic #13 // String.format:(LString;[LObject;)LString; 16: areturn
  • 115. JMH With amber-compiler intrinsics it’s not slow anymore ! score error test_concat 0.014 µs/op 0.001 µs/op test_builder 0.014 µs/op 0.001 µs/op test_format 0.014 µs/op 0.001 µs/op
  • 116. Amber / intrinsics The compiler uses invokedynamic instead public static java.lang.String format(int); 0: iload_0 1: invokedynamic #10, 0 // #1:format:(I)LString; 6: areturn bootstraps 1: #35 invokeStatic IntrinsicFactory.staticStringFormatBootstrap (LLookup;LString;LmethodType;LString;)LCallSite; Method arguments: #36 err: %d !
  • 117. Limitations Only works if – the format is a constant! – the format has no dependency on java.util.Locale! (double formatting) In the work – should work for JIT constant not only compiler constant – Consider the Locale as a constant + deoptimisation
  • 119. Example in Java Java class initialization is lazy by default => so not issue here! But static block initialization is the devil Usually trigger other class initializations => applications are slooow to boot
  • 120. Use Scala’s lazy keyword class Utils { public static final lazy Path HOME = Path.of(System.getenv("HOME")); } Problem: Scala uses the Double-checked Locking pattern
  • 121. The Double-checked Pattern The correct implementation disables further useful optimizations :( class Utils { private static volatile Path HOME; public static Path getHome() { var home = HOME; // volatile read if (home == null) { synchronized(Utils.class) { home = HOME; if (home == null) { return HOME = Path.of(System.getenv("HOME")); } } } return home; } }
  • 122. Constant Pool A classfile has a dictionnary of all constants (constant pool), each constant is transformed once to a runtime Java Object #30: ... #31: Utf8: "hello riviera dev" #32: String: #31 #33: ... class Utils { public static void main(String[] args) { //System.out.println("hello riviera dev"); ldc #32 ... } }
  • 123. Constant Dynamic ConstandDynamic (Java 11) is a constant that can be computed dynamically #28: Utf8: "Ljava/nio/file/Path;" #29: Utf8: "HOME" #30: NameAndType: #29:#28 // HOME Ljava/nio/file/Path; #31: MethodHandle 6:#… // Utils.lazy_HOME_init ()Ljava/nio/file/Path; #32: ConstantDynamic: 00:#30 BootstrapMethods: 00: #31 class Utils { private static Path lazy_HOME_init() { return Path.of(System.getenv("HOME")); } public static void main(String[] args) { //System.out.println(??); ldc #32 ... } }
  • 124. Demo !
  • 125. Compilation Strategies A lazy static field Loaded from the same class ● Use ldc Loaded from another class ● Use getstatic ?
  • 126. getstatic Opcode getstatic need to be changed to recognize attribute DynamicValue #30: NameAndType: #29:#28 // HOME Ljava/nio/file/Path; #31: MethodHandle 6:#… // Utils.lazy_HOME_init ()Ljava/nio/file/Path; #32: ConstantDynamic: 00:#30 #33: Field …:#30 // Utils.HOME Ljava/nio/file/Path; BootstrapMethods: 00: #31 class Utils { field: #30 DynamicValue: #32 private static Path lazy_HOME_init() { return Path.of(System.getenv("HOME")); } public static void main(String[] args) { //System.out.println(??); getstatic #33 ... } }
  • 127. Lazy static : Java vs Scala Scala (double-checked pattern) – Guarantee singleton – Perf issue: Volatile read + nullcheck Java (getstatic + constant dynamic) – Singleton after creation ● need to be idempotent – Plain static final read ● constant for the VM
  • 128. Lazy static final in Java Scheduled to be introduced in Java 14 “lazy” can not be used on final instance field
  • 130. Example in Java Embedded code is unreadable var html = "<html>n" + " <body style="width: 100vw">n" + " <p>Hello World.</p>n" + " </body>n" + " <script>console.log("loadedn")</script>n" + "</html>";
  • 131. Example in Java Embedded code has a lot of boilerplate var html = "<html>n" + " <body style="width: 100vw">n" + " <p>Hello World.</p>n" + " </body>n" + " <script>console.log("loadedn")</script>n" + "</html>";
  • 132. Borrow C# raw string var html = @"<html> <body style=""width: 100vw""> <p>Hello World.</p> </body> <script>console.log(""loadedn"")</script> </html>"; but with a different delimiter – C# needs to de-specialized quotes – we can not embed C# easily in Java
  • 133. Proposed Solution – Fat String Use """ to start and end a fat strings var html = """<html> <body style="width: 100vw"> <p>Hello World.</p> </body> <script>console.log("loadedn")</script> </html>""";
  • 134. Examples With pattern matching var pattern = Pattern.compile(""""""); A multi-lines string var s = """this is a long multi-lines of text"""; Embedded code var s = """< a href="javascript: alert('hello')">""";
  • 135. Fat/Raw String in Java Was initially scheduled for Java 11 Was a real raw String (no escape of u….) Using a variable number of backticks (`) But early adopter reactions were “meeh” Still in discussion Raw ? Auto-alignment ?