a post-apocalyptic sun.misc.unsafe world

105
http://www.superbwallpapers.com/fantasy/post-apocalyptic-tower-bridge-london-26546/ A Post-Apocalyptic sun.misc.Unsafe World

Upload: christoph-engelbert

Post on 16-Apr-2017

2.876 views

Category:

Software


0 download

TRANSCRIPT

Page 1: A Post-Apocalyptic sun.misc.Unsafe World

http://www.superbwallpapers.com/fantasy/post-apocalyptic-tower-bridge-london-26546/

A Post-Apocalypticsun.misc.Unsafe

World

Page 2: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

DisclaimerThis talk is not going to be negative!

Page 3: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Who’s that dude?• Chris Engelbert • Manager of Developer Relations @Hazelcast

• Java-Passionate (10+ years)

• Performance • Garbage Collection • Benchmark Fairytales

Page 4: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

sun.misc.Unsafe?

Page 5: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

sun.misc.Unsafe?

dangerous

low level

discourageperformance

platform specificpointers

UNSAFE

Page 6: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

sun.misc.Scissors

Page 7: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

“My precious.”

Page 8: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

“My precious.”The Lord of the Rings

Page 9: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Internal Class of the JDK

Page 10: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Internal Class of the JDKand those are not intended for outside use :)

Page 11: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Used inside and outside the JDK / JRE

custom (64-bit)

memory allocation

fastmemory access

fast

(de)serialization

minimizegc overhead

custommemory fences

efficientmemory layout(array element)

volatile semantics

Page 12: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Used inside and outside the JDK / JRE// Unsafe mechanicsprivate static final sun.misc.Unsafe U; private static final long QBASE; private static final long QLOCK; private static final int ABASE; private static final int ASHIFT; static { try { U = sun.misc.Unsafe.getUnsafe(); Class<?> k = WorkQueue.class; Class<?> ak = ForkJoinTask[].class; QBASE = U.objectFieldOffset (k.getDeclaredField("base")); QLOCK = U.objectFieldOffset (k.getDeclaredField("qlock")); ABASE = U.arrayBaseOffset(ak); int scale = U.arrayIndexScale(ak); if ((scale & (scale - 1)) != 0) throw new Error("data type scale not a power of two"); ASHIFT = 31 - Integer.numberOfLeadingZeros(scale); } catch (Exception e) { throw new Error(e); } }}

example: java.util.concurrent.ForkJoinPool

Page 13: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

“I’m the kind of the world!”

Page 14: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

“I’m the kind of the world!”Titanic

Page 15: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Used inside and outside the JDK / JRE

Page 16: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Used inside and outside the JDK / JRE

Page 17: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

## A fatal error has been detected by the Java Runtime Environment:## SIGSEGV (0xb) at pc=0x00000001067314b5, pid=25244, tid=5891## JRE version: Java(TM) SE Runtime Environment (8.0_05-b13) (build 1.8.0_05-b13)# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.5-b02 mixed mode bsd-amd64 compressed oops)# Problematic frame:# V [libjvm.dylib+0x5314b5] Unsafe_SetNativeAddress+0x36## An error report file with more information is saved as:# /Users/noctarius/git/hazelcast-only.idea/hs_err_pid25244.log## If you would like to submit a bug report, please visit:# http://bugreport.sun.com/bugreport/crash.jsp#

Page 18: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Page 19: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

“Supercalifragilisticexpialidocious!”

Page 20: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

“Supercalifragilisticexpialidocious!”Mary Poppins

Page 21: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Used inside and outside the JDK / JRE

MapDBNettyHazelcast

Cassandra Mockito

EasyMock

JMock

ScalaRobolectric

Grails

GsonNeo4j

Apache Ignite

Apache Spark

Apache KafkaApache Storm

Apache Continuum

Zookeeper

Dropwizard

Kryo

Byte Buddy

Hibernate

Liquibase

Spring Framework

Ehcache

OrientDB

Chronicle

Apache Hadoop

Apache HBase GWTDisruptor

JRubyAkka

Agrona

AeronSimple Binary Encoding

XRebel

Presto

jol

LWJGL

XAP

XStream

CapLogic

WildFly

Infinispan

Page 22: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Used inside and outside the JDK / JRE

MapDBNettyHazelcast

Cassandra Mockito

EasyMock

JMock

ScalaRobolectric

Grails

GsonNeo4j

Apache Ignite

Apache Spark

Apache KafkaApache Storm

Apache Continuum

Zookeeper

Dropwizard

Kryo

Byte Buddy

Hibernate

Liquibase

Spring Framework

Ehcache

OrientDB

Chronicle

Apache Hadoop

Apache HBase GWTDisruptor

JRubyAkka

Agrona

AeronSimple Binary Encoding

XRebel

Presto

jol

LWJGL

XAP

XStream

CapLogic

WildFly

Infinispan

Page 23: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Used inside and outside the JDK / JRE

MapDBNetty HazelcastCassandra Mockito

EasyMock

JMock

ScalaRobolectric

Grails

GsonNeo4j

Apache Ignite

Apache Spark

Apache KafkaApache Storm

Apache Continuum

Zookeeper

Dropwizard

Kryo

Byte Buddy

Hibernate

Liquibase

Spring Framework

Ehcache

OrientDB

Chronicle

Apache Hadoop

Apache HBase GWTDisruptor

JRubyAkka

Agrona

AeronSimple Binary Encoding

XRebel

Presto

jol

LWJGL

XAP

XStream

CapLogic

WildFly

Infinispan

Page 24: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Hazelcast Use Cases

Page 25: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Hazelcast Use Cases

Page 26: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Hazelcast Use Casescustom (64-bit)

memory allocation

fastmemory access

fast

(de)serialization

minimizegc overhead

custom memory fences

efficient memory layout(array element)

volatile semantics

Page 27: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

“There’s no place like home.”

Page 28: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

“There’s no place like home.”The Wizard of Oz

Page 29: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Page 30: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Close ;-)Language URL sun.misc.Unsafe

Avian C++ https://github.com/ReadyTalk/avian YesBicaVM JavaScript https://github.com/nurv/BicaVM NoCacao C http://www.cacaojvm.org Yes

Excelsior JVM C / C++ ? http://www.excelsiorjet.com YesDalvik / ART / Android C / C++ https://source.android.com/source/index.html Yes

Graal mainly Java http://openjdk.java.net/projects/graal YesGCJ C / C++ https://gcc.gnu.org/java Yes

HaikuVM C http://haiku-vm.sourceforge.net NoIBM J9 C / C++ ? http://www.ibm.com/developerworks/java/jdk/index.html YesIcedTea C / C++ http://icedtea.classpath.org/wiki/Main_Page Yes

IKVM.NET C# http://www.ikvm.net YesJamiga C https://sourceforge.net/projects/jamiga2 NoJamVM C http://jamvm.sourceforge.net YesJatoVM C http://jatovm.org Yes

JikesRVM C microkernel, Java http://www.jikesrvm.org YesJNode C microkernel, Java http://www.jnode.org YesJVM.go Go https://github.com/zxh0/jvm.go Yes

JX C http://www4.cs.fau.de/Projects/JX/index.html NoKaffe C https://github.com/kaffe/kaffe Yes

NanoVM C http://harbaum.org/till/nanovm/index.shtml NoOpenJDK / Oracle / Zulu C / C++ http://openjdk.java.net Yes

RoboVM C / C++ / ObjC https://robovm.com YesSAPJVM C / C++ ? http://help.sap.com/saphelp_nwce10/helpdata/en/47/

dc90b4ef17452289f9128b8c2bbd77/content.htmYes

Waratek Multitenant JVM C / C++ ? http://www.waratek.com YesZing JVM C / C++ ? https://www.azul.com/products/zing Yes

Page 31: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

“To infinity and beyond!”

Page 32: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

“To infinity and beyond!”Toy Story

Page 33: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

http://mail.openjdk.java.net/pipermail/openjfx-dev/2015-April/017028.html

Let me be blunt -- sun.misc.Unsafe must die in a fire. It is -- wait for it -- Unsafe. It must go. Ignore any kind of theoretical rope and

start the path to righteousness _*/now/*_. It is still years until the end of public updates to JDK 8, so we have /*years */to work this out

properly. But sticking our heads in the collective sands and hoping for trivial work arounds to Unsafe is not going to work. If you're using

Unsafe, this is the year to explain where the API is broken and get it straight....

Please help us kill Unsafe, kill Unsafe dead, kill Unsafe right, and do so as quickly as possible to the ultimate benefit of everyone.

Wed Apr 8 19:15:42 UTC 2015, OpenJFX Mailinglist, Donald Smith, Oracle

Page 34: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

http://mail.openjdk.java.net/pipermail/openjfx-dev/2015-April/017028.html

Let me be blunt -- sun.misc.Unsafe must die in a fire. It is -- wait for it -- Unsafe. It must go. Ignore any kind of theoretical rope and

start the path to righteousness _*/now/*_. It is still years until the end of public updates to JDK 8, so we have /*years */to work this out

properly. But sticking our heads in the collective sands and hoping for trivial work arounds to Unsafe is not going to work. If you're using

Unsafe, this is the year to explain where the API is broken and get it straight....

Please help us kill Unsafe, kill Unsafe dead, kill Unsafe right, and do so as quickly as possible to the ultimate benefit of everyone.

Wed Apr 8 19:15:42 UTC 2015, OpenJFX Mailinglist, Donald Smith, Oracle

Page 35: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Oracle created a new Taskforce

Page 36: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Oracle created a new Taskforce

K.U.T.T. - Kill Unsafe To Total death

Page 37: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

http://mail.openjdk.java.net/pipermail/openjfx-dev/2015-April/017028.html

Let me be blunt -- sun.misc.Unsafe must die in a fire. It is -- wait for it -- Unsafe. It must go. Ignore any kind of theoretical rope and

start the path to righteousness _*/now/*_. It is still years until the end of public updates to JDK 8, so we have /*years */to work this out

properly. But sticking our heads in the collective sands and hoping for trivial work arounds to Unsafe is not going to work. If you're using

Unsafe, this is the year to explain where the API is broken and get it straight....

Please help us kill Unsafe, kill Unsafe dead, kill Unsafe right, and do so as quickly as possible to the ultimate benefit of everyone.

Wed Apr 8 19:15:42 UTC 2015, OpenJFX Mailinglist, Donald Smith, Oracle

Page 38: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

https://docs.google.com/document/d/1GDm_cAxYInmoHMor-AkStzWvwE9pw6tnz_CebJQxuUE

Hazelcast

jClarityAzul Systems

Higher Frequency Trading

Rafael Winterhalter

Richard Warburton

and many others…

Page 39: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Page 40: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Page 41: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Page 42: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Mutation: it is the key to our evolution.

Page 43: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Mutation: it is the key to our evolution.X-Men

Page 44: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 1: Get Access

Page 45: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 1: Get Access

Unsafe unsafe = Unsafe.getUnsafe();Easy One (not working outside the JRE / JDK)

Page 46: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 1: Get Access

private static final Unsafe UNSAFE; static { try { Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafeField.setAccessible(true); UNSAFE = (Unsafe) theUnsafeField.get(Unsafe.class); } catch (Exception e) { // We need you! =( throw new Error(e); }}

The Ugly One

Page 47: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 1: Get Accessprivate static Unsafe findUnsafe() { try { return Unsafe.getUnsafe(); } catch (SecurityException se) { return AccessController.doPrivileged(new PrivilegedAction<Unsafe>() { @Override public Unsafe run() { try { Class<Unsafe> type = Unsafe.class; try { Field field = type.getDeclaredField("theUnsafe"); field.setAccessible(true); return type.cast(field.get(type)); } catch (Exception e) { for (Field field : type.getDeclaredFields()) { if (type.isAssignableFrom(field.getType())) { field.setAccessible(true); return type.cast(field.get(type)); } } } } catch (Exception e) { throw new RuntimeException("Unsafe unavailable", e); } throw new RuntimeException("Unsafe unavailable"); } }); }}

The Hazelcast One(also working in most other JVMs)

Page 48: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 1: Get Access

The Tricky Oneprivate static final Unsafe UNSAFE; static { try { Constructor<Unsafe> constructor = Unsafe.class.getDeclaredConstructor(); constructor.setAccessible(true); UNSAFE = constructor.newInstance(); } catch (Exception e) { // We need you! =( throw new Error(e); }}

Page 49: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 1: Get Access

The Tricky Oneprivate static final Unsafe UNSAFE; static { try { Constructor<Unsafe> constructor = Unsafe.class.getDeclaredConstructor(); constructor.setAccessible(true); UNSAFE = constructor.newInstance(); } catch (Exception e) { // We need you! =( throw new Error(e); }}

Page 50: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 1: Get Access

Does Any Of This Feel Right?

Page 51: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 1: Get Access

Weird!

No!

Page 52: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 1: Get Access

WAAAAAT!?!?

No!

Page 53: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Solution 1: Get Access

Page 54: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Solution 1: Get Access

Nothing; not needed anymore!

Page 55: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 2: Atomic Updatesprivate static final Unsafe UNSAFE = findUnsafe();private static long VERSION_OFFSET = findVersionOffset();

// Updated through Unsafe only!private volatile long version = 0;

public long increment() { while(true) { long version = this.version; long newVersion = version + 1; if (UNSAFE.compareAndSwapLong( this, VERSION_OFFSET, version, newVersion)) {

return newVersion; } }}

Going Unsafe

Page 56: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 2: Atomic Updates

We can do better! There’s an API already!

Page 57: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 2: Atomic Updates

private final AtomicLong version = new AtomicLong(0);

public long increment() { return version.incrementAndGet();}

We can do better! There’s an API already!

But one AtomicLong instance per version

Page 58: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 2: Atomic Updates

We can still do better! There’s yet another API already!

Page 59: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 2: Atomic Updates

We can still do better! There’s yet another API already!private static final AtomicLongFieldUpdater<Record> VERSION = AtomicLongFieldUpdater.newUpdater(Record, "version");

// Updated through atomic field updater only! private volatile long version = 0; public long increment() { return VERSION.incrementAndGet(this); }

Page 60: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Solution 2: Atomic Updates

We can still do better! There’s yet another API already!private static final AtomicLongFieldUpdater<Record> VERSION = AtomicLongFieldUpdater.newUpdater(Record, "version");

// Updated through atomic field updater only! private volatile long version = 0; public long increment() { return VERSION.incrementAndGet(this); }

You guessed it, __ uses it ;-)

Page 61: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Solution 2: Atomic Updates

private static final VarHandle VERSION = findVersionVarHandle();// Updated through VarHandle only!private volatile long version = 0; public long increment() { return (long) VERSION.addAndGet(this, 1);}

JVM can inline those calls

Page 62: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Solution 2: Atomic Updates

public static VarHandle findVersionVarHandle() { try { return MethodHandles.lookup(). findFieldVarHandle(Record.class, "version", long.class); } catch (Exception e) { throw new Error(e); }}

Statically cache the VarHandle instance

Page 63: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 3: Memory Management

public long memory() { long address = UNSAFE.allocateMemory(8); UNSAFE.putLong(address, Long.MAX_VALUE); return UNSAFE.getLong(address);}

Keyword: Off-Heap

Page 64: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 3: Memory Management

ByteBuffer possible; API is 32bit though

public long memory() { ByteBuffer byteBuffer = ByteBuffer.allocateDirect(8); byteBuffer.putLong(0, Long.MAX_VALUE); return byteBuffer.getLong(0);}

Page 65: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Solution 3: Memory Management

public long memory() { ByteBuffer byteBuffer = ByteBuffer.allocateDirect(8); VarHandle bufferView = MethodHandles.byteBufferViewVarHandle(long[].class, true); bufferView.set(byteBuffer, 0, Long.MAX_VALUE); return bufferView.get(byteBuffer, 0); }

Simplifies off-heap implementations,empowers new ideas

Page 66: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Solution 3.5: Memory Management

Even easier to build a great off-heap

public long memory(long index) { try (Scope scope = new NativeScope()) { Pointer<Long> ptr = scope.allocate( NativeLibrary.createLayout(long.class), numElements); Reference<Long> ref = ptr.offset(index).deref(); ref.set(Long.MAX_VALUE); return ref.get(); }}

Page 67: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 4: Serialization

private static final Unsafe UNSAFE = findUnsafe();private static final long VALUE_OFFSET = findValueOffset();public String deserializeString() throws Exception { char[] chars = magicallyDecodeUTF8FromStream(); String allocated = (String) UNSAFE.allocateInstance(String.class); UNSAFE.putObjectVolatile(allocated, VALUE_OFFSET, chars); return allocated;}

Page 68: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 4: Serialization

private static final Unsafe UNSAFE = findUnsafe();private static final long VALUE_OFFSET = findValueOffset();public String deserializeString() throws Exception { char[] chars = magicallyDecodeUTF8FromStream(); String allocated = (String) UNSAFE.allocateInstance(String.class); UNSAFE.putObjectVolatile(allocated, VALUE_OFFSET, chars); return allocated;}

Will break in Java 9 (compressed Strings)

Page 69: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Solution 4: Serialization

public String deserializeString() throws Exception { char[] chars = magicallyDecodeUTF8FromStream(); ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory(); Constructor<String> constructor = reflectionFactory .newConstructorForSerialization(String.class, char[].class); return constructor.newInstance(chars);}

sun.reflect.ReflectionFactory -> java.lang.reflect.ReflectionFactory (or similar)

Page 70: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 5: Native Interoperabilityextern c { JNIEXPORT int JNICALL Java_ProcessIdentifier_getProcessId(JNIEnv *, jobject);} JNIEXPORT int JNICALLJava_ProcessIdentifier_getProcessId(JNIEnv *env, jobject thisObj) { return getpid();} public class ProcessIdentifier { static { System.loadLibrary("processidentifier"); } public native void getProcessId();}

Page 71: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 5: Native Interoperabilityextern c { JNIEXPORT int JNICALL Java_ProcessIdentifier_getProcessId(JNIEnv *, jobject);} JNIEXPORT int JNICALLJava_ProcessIdentifier_getProcessId(JNIEnv *env, jobject thisObj) { return getpid();} public class ProcessIdentifier { static { System.loadLibrary("processidentifier"); } public native void getProcessId();}

Fortunately we don’t deal with it, but who loves it anyways ;-)

Page 72: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Solution 5: Native Interoperability (for now)

interface LibC { void getpid();} public int call() { LibC c = LibraryLoader.create(LibC.class).load("c"); return c.getpid();}

JNR, but guess what it uses internally ;-)

Page 73: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Solution 5: Native Interoperability

public void call() { MethodType intType = MethodType.methodType(int.class); MethodHandle handle = MethodHandles .findNative(null, “getpid”, intType); return (int) handle.invokeExact();}

They inline … just fine.

Page 74: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 6: Immutable Types

Defensive Copies, no real optimization yet

Page 75: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Solution 6: Immutable Types

value class Point { final int x; final int y; } // Create a Point instancePoint point = makeValue(1, 2);

Value Types

Page 76: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Solution 6: Immutable Types

int[] values = new int[2];int x = values[0]; int y = values[1];

Looks like

value class Point { final int x; final int y; } // Create a Point instancePoint point = makeValue(1, 2);

Value Types

Page 77: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Solution 6: Immutable Types

value class Point { final int x; final int y; } // Create a Point instancePoint point = makeValue(1, 2);

Value Types int[] values = new int[2];int x = values[0]; int y = values[1];

Stack

var X

var Y

Looks like

Stack Allocation!

Page 78: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 7: Generics

HazelcastInstance client = HazelcastClient.newHazelcastClient();Map<Long, String> messages = client.getMap("messages");String message = messages.get(1234L);

No generics on primitives

Page 79: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 7: Generics

HazelcastInstance client = HazelcastClient.newHazelcastClient();Map<Long, String> messages = client.getMap("messages");String message = messages.get(1234L);

No generics on primitives

Auto-(Un)Boxing

Page 80: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Problem 7: Generics

HazelcastInstance client = HazelcastClient.newHazelcastClient();Map<Long, String> messages = client.getMap("messages");String message = messages.get(1234L);

No generics on primitives

Auto-(Un)Boxing

Page 81: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Solution 7: Generics

class Box<any T> { void set(T element) { ... }; T get() { ... };}

Specialized Generics (yeah it’s kind of a template)

Page 82: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Solution 7: Generics

class Box<any T> { void set(T element) { ... }; T get() { ... };}

Specialized Generics (yeah it’s kind of a template)

Box<int> Box${T=int}.classBox<String> Box${T=java.lang.String}.classBox<RandomClass> Box${T=RandomClass}.class

Page 83: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Solution 7: Genericspublic void generics() { List<int> intList = client.getList("foo"); intList.add(1); int intValue = intList.get(0); Queue<String> stringQueue = client.getQueue("foo"); stringQueue.offer("hello"); String stringValue = stringQueue.poll(); Map<int, String> messages = client.getMap("messages"); messages.put(1234L, "hello"); String message = messages.get(1234L); }

Page 84: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Page 85: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Arrays 2.0

int[] values = new int[Long.MAX_VALUE];

Page 86: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Arrays 2.0

int[] values = new int[Long.MAX_VALUE];

Arrays.chop(T[] a, int newlength);

Page 87: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Arrays 2.0

int[] values = new int[Long.MAX_VALUE];

Arrays.chop(T[] a, int newlength);

Box<String>[] ... = new Box<String>[];

Page 88: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Arrays 2.0

int[] values = new int[Long.MAX_VALUE];

Arrays.chop(T[] a, int newlength);

Box<int>[] ... = new Box<int>[];

Page 89: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Arrays 2.0

int[] values = new int[Long.MAX_VALUE];

Arrays.chop(T[] a, int newlength);

Box<int>[] ... = new Box<int>[];

char[] frozen = new char[20L].freeze();

Page 90: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Arrays 2.0

int[] values = new int[Long.MAX_VALUE];

Arrays.chop(T[] a, int newlength);

Box<int>[] ... = new Box<int>[];

char[] frozen = new char[20L].freeze();

Page 91: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Cleaner APIpackage java.nio;

import sun.misc.Cleaner;

class DirectByteBuffer extends MappedByteBuffer implements DirectBuffer {

private static class Deallocator implements Runnable { private Deallocator(long address, long size, int capacity) {...}

public void run() {...} }

private final Cleaner cleaner; DirectByteBuffer(int cap) { ... cleaner = Cleaner.create(this, new Deallocator(base, size, cap)); } }

Page 92: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Cleaner API

public selfCleaning() { try(AutoCleaning autoCleaning : new AutoCleaning()) { // do your thing here } }

Page 93: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Cleaner APIpublic class AutoCleaning implements AutoCloseable { // A cleaner, preferably one shared within a library private static final Cleaner cleaner = ...;

static class State implements Runnable {

State(...) {/* initialize State needed for cleaning action */} public void run() {/*cleanup action accessing State, executed at most once*/} }

private final State state; private final Cleaner.Cleanable cleanable;

public AutoCleaning() { this.state = new State(...); this.cleanable = cleaner.register(this, state); }

public void close() { cleanable.clean(); }}

Page 94: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Class Dynamic

• Templating functionality

Page 95: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Class Dynamic

• Templating functionality • Aspect-like approach

Page 96: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Class Dynamic

• Templating functionality • Aspect-like approach • Group common functionality

Page 97: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Class Dynamic

• Templating functionality • Aspect-like approach • Group common functionality • Enhanced Proxies

R methodName(ARGS) { synchronized (this) { underlying.methodName(ARGS); }}

Collections::sychronizedMap

Page 98: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Class Dynamic

• Templating functionality • Aspect-like approach • Group common functionality • Enhanced Proxies

Logging / Tracing

R methodName(ARGS) { logger.trace("Before methodname X"); underlying.methodName(ARGS); logger.trace("After methodname X");}

Page 99: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

What Else?

No idea!

A lot is changing now.Java / JVM will be different.

… but lots of interesting features, not only for us :)

Page 100: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

What Else?

Don’t forget about Jigsaw,test your application with Java 9 EA builds!

https://jdk9.java.net/jigsaw/

Page 101: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

“My mama always said, ‘Life was like a box of chocolates. You never know what you’re gonna get.”

Page 102: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

“My mama always said, ‘Life was like a box of chocolates. You never know what you’re gonna get.”

Forrest Gump

Page 103: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Thank You!Any Questions?

@noctarius2k http://www.sourceprojects.org

http://github.com/noctarius

@hazelcast http://www.hazelcast.com http://www.hazelcast.org

http://github.com/hazelcast

Page 104: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

More information:• http://openjdk.java.net/jeps/193 • http://openjdk.java.net/jeps/254 • http://openjdk.java.net/jeps/285 • http://openjdk.java.net/projects/valhalla/ • http://cr.openjdk.java.net/~jrose/arrays/frozen-array-value-rules.html • https://twitter.com/PaulSandoz/status/623891528432394240 • http://openjdk.java.net/projects/panama/ • http://cr.openjdk.java.net/~jrose/values/values-0.html • http://cr.openjdk.java.net/~briangoetz/valhalla/spec-classdyn.html • http://blog.codefx.org/java/dev/the-road-to-valhalla/

Thank You!

Page 105: A Post-Apocalyptic sun.misc.Unsafe World

www.hazelcast.com@noctarius2k

Thank You!http://openjdk.java.net/jeps/259 http://openjdk.java.net/jeps/286 http://openjdk.java.net/jeps/276 http://openjdk.java.net/jeps/269 http://openjdk.java.net/jeps/266 http://openjdk.java.net/jeps/191 http://openjdk.java.net/jeps/186 http://openjdk.java.net/jeps/277