a post-apocalyptic sun.misc.unsafe world
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