a post-apocalyptic sun.misc.unsafe world

Post on 16-Apr-2017

2.876 Views

Category:

Software

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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

A Post-Apocalypticsun.misc.Unsafe

World

www.hazelcast.com@noctarius2k

DisclaimerThis talk is not going to be negative!

www.hazelcast.com@noctarius2k

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

• Java-Passionate (10+ years)

• Performance • Garbage Collection • Benchmark Fairytales

www.hazelcast.com@noctarius2k

sun.misc.Unsafe?

www.hazelcast.com@noctarius2k

sun.misc.Unsafe?

dangerous

low level

discourageperformance

platform specificpointers

UNSAFE

www.hazelcast.com@noctarius2k

sun.misc.Scissors

www.hazelcast.com@noctarius2k

“My precious.”

www.hazelcast.com@noctarius2k

“My precious.”The Lord of the Rings

www.hazelcast.com@noctarius2k

Internal Class of the JDK

www.hazelcast.com@noctarius2k

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

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

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

www.hazelcast.com@noctarius2k

“I’m the kind of the world!”

www.hazelcast.com@noctarius2k

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

www.hazelcast.com@noctarius2k

Used inside and outside the JDK / JRE

www.hazelcast.com@noctarius2k

Used inside and outside the JDK / JRE

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#

www.hazelcast.com@noctarius2k

www.hazelcast.com@noctarius2k

“Supercalifragilisticexpialidocious!”

www.hazelcast.com@noctarius2k

“Supercalifragilisticexpialidocious!”Mary Poppins

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

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

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

www.hazelcast.com@noctarius2k

Hazelcast Use Cases

www.hazelcast.com@noctarius2k

Hazelcast Use Cases

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

www.hazelcast.com@noctarius2k

“There’s no place like home.”

www.hazelcast.com@noctarius2k

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

www.hazelcast.com@noctarius2k

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

www.hazelcast.com@noctarius2k

“To infinity and beyond!”

www.hazelcast.com@noctarius2k

“To infinity and beyond!”Toy Story

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

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

www.hazelcast.com@noctarius2k

Oracle created a new Taskforce

www.hazelcast.com@noctarius2k

Oracle created a new Taskforce

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

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

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…

www.hazelcast.com@noctarius2k

www.hazelcast.com@noctarius2k

www.hazelcast.com@noctarius2k

www.hazelcast.com@noctarius2k

Mutation: it is the key to our evolution.

www.hazelcast.com@noctarius2k

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

www.hazelcast.com@noctarius2k

Problem 1: Get Access

www.hazelcast.com@noctarius2k

Problem 1: Get Access

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

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

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)

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); }}

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); }}

www.hazelcast.com@noctarius2k

Problem 1: Get Access

Does Any Of This Feel Right?

www.hazelcast.com@noctarius2k

Problem 1: Get Access

Weird!

No!

www.hazelcast.com@noctarius2k

Problem 1: Get Access

WAAAAAT!?!?

No!

www.hazelcast.com@noctarius2k

Solution 1: Get Access

www.hazelcast.com@noctarius2k

Solution 1: Get Access

Nothing; not needed anymore!

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

www.hazelcast.com@noctarius2k

Problem 2: Atomic Updates

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

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

www.hazelcast.com@noctarius2k

Problem 2: Atomic Updates

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

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); }

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 ;-)

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

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

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

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);}

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

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(); }}

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;}

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)

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)

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();}

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 ;-)

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 ;-)

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.

www.hazelcast.com@noctarius2k

Problem 6: Immutable Types

Defensive Copies, no real optimization yet

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

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

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!

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

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

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

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)

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

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); }

www.hazelcast.com@noctarius2k

www.hazelcast.com@noctarius2k

Arrays 2.0

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

www.hazelcast.com@noctarius2k

Arrays 2.0

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

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

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>[];

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>[];

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();

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();

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)); } }

www.hazelcast.com@noctarius2k

Cleaner API

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

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(); }}

www.hazelcast.com@noctarius2k

Class Dynamic

• Templating functionality

www.hazelcast.com@noctarius2k

Class Dynamic

• Templating functionality • Aspect-like approach

www.hazelcast.com@noctarius2k

Class Dynamic

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

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

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");}

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 :)

www.hazelcast.com@noctarius2k

What Else?

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

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

www.hazelcast.com@noctarius2k

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

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

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

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!

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

top related