Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
http://www.superbwallpapers.com/fantasy/post-apocalyptic-tower-bridge-london-26546/
A Post-Apocalyptic
sun.misc.Unsafe
Wor...
www.hazelcast.com@noctarius2k
Who’s that dude?
• Chris Engelbert
• Manager Developer Relations @Hazelcast
• Twitter-Senpai...
Disclaimer
This talk is not going to be negative!
Disclaimer
But certain things are highly speculative

and APIs or ideas might change by
tomorrow!
http://www.underwhelmedcomic.com/wp-content/uploads/2012/03/runningdude.jpg
sun.misc.Scissors
sun.misc.Unsafe - What you (don’t) know
sun.misc.Unsafe - What you (don’t) know
• Internal class (sun.misc Package)
sun.misc.Unsafe - What you (don’t) know
• Internal class (sun.misc Package)
sun.misc.Unsafe - What you (don’t) know
• Internal class (sun.misc Package)
• Used inside the JVM / JRE
sun.misc.Unsafe - What you (don’t) know
• Internal class (sun.misc Package)
• Used inside the JVM / JRE
// Unsafe mechanic...
sun.misc.Unsafe - What you (don’t) know
• Internal class (sun.misc Package)
• Used inside the JVM / JRE
• Used outside as ...
sun.misc.Unsafe - What you (don’t) know
• Internal class (sun.misc Package)
• Used inside the JVM / JRE
• Used outside as ...
sun.misc.Unsafe - What you (don’t) know
• Internal class (sun.misc Package)
• Used inside the JVM / JRE
• Used outside as ...
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00000001067314b5, pid=25244...
sun.misc.Unsafe - What you (don’t) know
• Internal class (sun.misc Package)
• Used inside the JVM / JRE
• Used outside as ...
sun.misc.Unsafe - What you (don’t) know
• Internal class (sun.misc Package)
• Used inside the JVM / JRE
• Used outside as ...
sun.misc.Unsafe - What you (don’t) know
• Internal class (sun.misc Package)
• Used inside the JVM / JRE
• Used outside as ...
MapDB
Netty
Hazelcast
Cassandra
Mockito
EasyMock
JMock
Scala
Spock
Robolectric
Grails
Gson
Neo4j
Apache Ignite
Apache Spar...
MapDB
Netty
Hazelcast
Cassandra
Mockito
EasyMock
JMock
Scala
Spock
Robolectric
Grails
Gson
Neo4j
Apache Ignite
Apache Spar...
sun.misc.Unsafe
is only supported on HotSpot JVMs anyways, isn’t it?
sun.misc.Unsafe
is only supported on HotSpot JVMs anyways, isn’t it?
No!
Language URL sun.misc.Unsafe
Avian C++ https://github.com/ReadyTalk/avian Yes
BicaVM JavaScript https://github.com/nurv/Bi...
Use Cases - The Good Ones!
Use Cases - The Good Ones!
• Low Latency, GC Overhead
Use Cases - The Good Ones!
• Low Latency, GC Overhead
Caution: Overly simplified!
Unsafe unsafe = findUnsafe();

long baseA...
Use Cases - The Good Ones!
• Low Latency, GC Overhead
• Fast (de-)serialization
Use Cases - The Good Ones!
• Low Latency, GC Overhead
• Fast (de-)serialization
// Deserialization
public Object readObjec...
Use Cases - The Good Ones!
• Low Latency, GC Overhead
• Fast (de-)serialization
• 64bit Memory regions
Use Cases - The Good Ones!
• Low Latency, GC Overhead
• Fast (de-)serialization
• 64bit Memory regions
long baseAddress = ...
Use Cases - The Good Ones!
• Low Latency, GC Overhead
• Fast (de-)serialization
• 64bit Memory regions
• Atomic memory ope...
Use Cases - The Good Ones!
• Low Latency, GC Overhead
• Fast (de-)serialization
• 64bit Memory regions
• Atomic memory ope...
Use Cases - The Good Ones!
• Low Latency, GC Overhead
• Fast (de-)serialization
• 64bit Memory regions
• Atomic memory ope...
Use Cases - The Good Ones!
• Low Latency, GC Overhead
• Fast (de-)serialization
• 64bit Memory regions
• Atomic memory ope...
Use Cases - The Good Ones!
• Low Latency, GC Overhead
• Fast (de-)serialization
• 64bit Memory regions
• Atomic memory ope...
Use Cases - The Good Ones!
• Low Latency, GC Overhead
• Fast (de-)serialization
• 64bit Memory regions
• Atomic memory ope...
Use Cases - The Good Ones!
• Low Latency, GC Overhead
• Fast (de-)serialization
• 64bit Memory regions
• Atomic memory ope...
Use Cases - The Good Ones!
• Low Latency, GC Overhead
• Fast (de-)serialization
• 64bit Memory regions
• Atomic memory ope...
Use Cases - The Good Ones!
• Low Latency, GC Overhead
• Fast (de-)serialization
• 64bit Memory regions
• Atomic memory ope...
Use Cases - The Good Ones!
• Low Latency, GC Overhead
• Fast (de-)serialization
• 64bit Memory regions
• Atomic memory ope...
Use Cases - The Good Ones!
• Low Latency, GC Overhead
• Fast (de-)serialization
• 64bit Memory regions
• Atomic memory ope...
Use Cases - The Good Ones!
• Low Latency, GC Overhead
• Fast (de-)serialization
• 64bit Memory regions
• Atomic memory ope...
Get Access
Get Access
Easy One (not working outside the JRE / JDK)
Unsafe unsafe = Unsafe.getUnsafe();
Get Access
The Ugly One
private static final Unsafe UNSAFE;

static {

try {

Field theUnsafeField = Unsafe.class.getDecla...
Get Access
The Working One
(at least for more than just HotSpot)
private static Unsafe findUnsafe() {

try {

return Unsaf...
Get Access
The Tricky One
private static final Unsafe UNSAFE;

static {

try {

Constructor<Unsafe> constructor =
Unsafe.c...
Get Access
Does Any Of This Feel Right?
Weird!
No!
WAAAAAT!?!?
No!
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 theor...
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 theor...
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 theor...
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 theor...
Oracle created a new Taskforce
Oracle created a new Taskforce
K.U.T.T. - Kill Unsafe To Total death
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 theor...
So What’s Coming?
private static final Unsafe UNSAFE = findUnsafe();
private static long VERSION_OFFSET = findVersionOffset();
// Updated th...
Atomic Updates
private final AtomicLong version = new AtomicLong(0);
public long increment() {
return version.incrementAnd...
Atomic Updates
private static final AtomicLongFieldUpdater<Record> VERSION =

AtomicLongFieldUpdater.newUpdater(Record, "v...
Atomic Updates
private static final VarHandle VERSION = findVersionVarHandle();



// Updated through VarHandle only!

pri...
Atomic Updates
public static VarHandle findVersionVarHandle() {

try {

return MethodHandles.lookup().

findFieldVarHandle...
Memory Management
public long memory() {

long address = UNSAFE.allocateMemory(8);


UNSAFE.putLong(address, Long.MAX_VALU...
Memory Management
public long memory() {

ByteBuffer byteBuffer = ByteBuffer.allocateDirect(8);



byteBuffer.putLong(0, L...
Memory Management
public long memory() {

ByteBuffer byteBuffer = ByteBuffer.allocateDirect(8);



VarHandle bufferView =
...
Memory Management
public long memory() {

MemoryRegion region = MemoryRegion.allocateNative

("myname", MemoryRegion.UNALI...
Memory Management
public long memory() {

MemoryRegion region = MemoryRegion.allocateNative

("myname", MemoryRegion.UNALI...
Memory Management
public long memory(long index) {

try (Scope scope = new NativeScope()) {

Pointer<Long> ptr = scope.all...
Memory Management
Deserialization
private static final Unsafe UNSAFE = findUnsafe();



private static final long VALUE_OFFSET = findValueOf...
Deserialization
public String deserializeString() throws Exception {

char[] chars = readCharsFromStream().freeze();



Re...
Interoperability
extern c {

JNIEXPORT int JNICALL

Java_ProcessIdentifier_getProcessId(JNIEnv *, jobject);

}



JNIEXPOR...
Interoperability
interface LibC {

void getpid();

}



public int call() {

LibC c = LibraryLoader.create(LibC.class).loa...
Interoperability
public void call() {
MethodType intType = MethodType.methodType(int.class);


MethodHandle handle = Metho...
Value Types
value class Point {

final int x;

final int y;

}



// Create a Point instance

Point point = makeValue(1, 2...
Value Types
int[] values = new int[2];

int x = values[0];

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

int x = values[0];

int y = values[1];
Stack
var X
var Y
Value Types
int[] values = new int[2];

int x = values[0];

int y = values[1];
Stack
var X
var Y
Stack Allocation!
Specialized Generics
class Box<any T> {

void set(T element) { ... };


T get() { ... };

}
Specialized Generics
class Box<any T> {

void set(T element) { ... };


T get() { ... };

}
Box<int> Box${T=int}.class

Bo...
Specialized Generics
public void generics() {

Box<int> intBox = new Box<>();

intBox.set(1);

int intValue = intBox.get()...
Arrays 2.0
int[] values = new int[Long.MAX_VALUE];
Arrays 2.0
int[] values = new int[Long.MAX_VALUE];
Arrays.chop(T[] a, int newlength);
Arrays 2.0
int[] values = new int[Long.MAX_VALUE];
Arrays.chop(T[] a, int newlength);
Box<String>[] ... = new Box<String>[...
Arrays 2.0
int[] values = new int[Long.MAX_VALUE];
Arrays.chop(T[] a, int newlength);
Box<int>[] ... = new Box<int>[];
Arrays 2.0
int[] values = new int[Long.MAX_VALUE];
Arrays.chop(T[] a, int newlength);
Box<int>[] ... = new Box<int>[];
cha...
Arrays 2.0
int[] values = new int[Long.MAX_VALUE];
Arrays.chop(T[] a, int newlength);
Box<int>[] ... = new Box<int>[];
cha...
Cleaner API
Who knows the Cleaner API?
You should - it’s around since Java 1.4 ;-)
Cleaner API
package java.nio;
import sun.misc.Cleaner;
class DirectByteBuffer

extends MappedByteBuffer

implements Direct...
Cleaner API
public selfCleaning() {

try(AutoCleaning autoCleaning : new AutoCleaning()) {

// do your thing here

}

}
Cleaner API
public class AutoCleaning implements AutoCloseable {
// A cleaner, preferably one shared within a library
priv...
More exciting
stuff upcoming…
Class Dynamic
Class Dynamic
•Templating functionality
Class Dynamic
•Templating functionality
•Aspect-like approach
Class Dynamic
•Templating functionality
•Aspect-like approach
•Group common functionality
Class Dynamic
•Templating functionality
•Aspect-like approach
•Group common functionality
•Enhanced Proxies
Class Dynamic
•Templating functionality
•Aspect-like approach
•Group common functionality
•Enhanced Proxies
R methodName(A...
Class Dynamic
•Templating functionality
•Aspect-like approach
•Group common functionality
•Enhanced Proxies
Logging / Trac...
Class Dynamic
•Templating functionality
•Aspect-like approach
•Group common functionality
•Enhanced Proxies
Your Use Case!
SpinWait Hints
SpinWait Hints
Hints the JVM that a busy spin’s upcoming
SpinWait Hints
Hints the JVM that a busy spin’s upcoming
JVM CAN intrinsify to use a WAIT opcode for the specific platform ...
SpinWait Hints
Hints the JVM that a busy spin’s upcoming
JVM CAN intrinsify to use a WAIT opcode for the specific platform ...
SpinWait Hints
Hints the JVM that a busy spin’s upcoming
JVM CAN intrinsify to use a WAIT opcode for the specific platform ...
What Else?
No idea!
A lot is changing now.
Java / JVM will be different.
What Else?
No idea!
A lot is changing now.
Java / JVM will be different.
Don’t forget about Jigsaw,
test your application ...
Questions?
github.com/noctarius
@noctarius2k
More information:
• http://openjdk.java.net/jeps/193
• http://openjdk.java.ne...
http://openjdk.java.net/jeps/259
http://openjdk.java.net/jeps/286
http://openjdk.java.net/jeps/276
http://openjdk.java.net...
A Post-Apocalyptic sun.misc.Unsafe World by Christoph engelbert
A Post-Apocalyptic sun.misc.Unsafe World by Christoph engelbert
A Post-Apocalyptic sun.misc.Unsafe World by Christoph engelbert
A Post-Apocalyptic sun.misc.Unsafe World by Christoph engelbert
Prochain SlideShare
Chargement dans…5
×

A Post-Apocalyptic sun.misc.Unsafe World by Christoph engelbert

The announcement that sun.misc.Unsafe will disappear in Java 9 created a huge buzz in the community and lots of people didn’t agree with the idea. While Unsafe have to go away eventually the time in not yet and Oracle finally agreed on that. To replace sun.misc.Unsafe we need a clear set of APIs to achieve the same behavior and performance. VarHandle, Foreign Function Calls, Generic Specialization (Templates) and other proposals try to solve this misery and to replace certain aspects of our beloved class. This talk will introduce the alternatives and explain how and why they will help to replace sun.misc.Unsafe. It uses basic examples to demonstrate what a Post-Apocalyptic Unsafe World will look like.

  • Identifiez-vous pour voir les commentaires

A Post-Apocalyptic sun.misc.Unsafe World by Christoph engelbert

  1. 1. http://www.superbwallpapers.com/fantasy/post-apocalyptic-tower-bridge-london-26546/ A Post-Apocalyptic sun.misc.Unsafe World
  2. 2. www.hazelcast.com@noctarius2k Who’s that dude? • Chris Engelbert • Manager Developer Relations @Hazelcast • Twitter-Senpai • Java-Passionist (10+ years) • Performance • Garbage Collection • Benchmark Fairytales
  3. 3. Disclaimer This talk is not going to be negative!
  4. 4. Disclaimer But certain things are highly speculative
 and APIs or ideas might change by tomorrow!
  5. 5. http://www.underwhelmedcomic.com/wp-content/uploads/2012/03/runningdude.jpg sun.misc.Scissors
  6. 6. sun.misc.Unsafe - What you (don’t) know
  7. 7. sun.misc.Unsafe - What you (don’t) know • Internal class (sun.misc Package)
  8. 8. sun.misc.Unsafe - What you (don’t) know • Internal class (sun.misc Package)
  9. 9. sun.misc.Unsafe - What you (don’t) know • Internal class (sun.misc Package) • Used inside the JVM / JRE
  10. 10. sun.misc.Unsafe - What you (don’t) know • Internal class (sun.misc Package) • Used inside the JVM / JRE // Unsafe mechanics
 private 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
  11. 11. sun.misc.Unsafe - What you (don’t) know • Internal class (sun.misc Package) • Used inside the JVM / JRE • Used outside as well
  12. 12. sun.misc.Unsafe - What you (don’t) know • Internal class (sun.misc Package) • Used inside the JVM / JRE • Used outside as well (good // Deserialization public Object readObject(InputStream is) {
 SomeType element = unsafe.allocateInstance(SomeType.class);
 element.deserializeValues(is);
 return element;
 }
  13. 13. sun.misc.Unsafe - What you (don’t) know • Internal class (sun.misc Package) • Used inside the JVM / JRE • Used outside as well (good, bad)
  14. 14. # # 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 #
  15. 15. sun.misc.Unsafe - What you (don’t) know • Internal class (sun.misc Package) • Used inside the JVM / JRE • Used outside as well (good / bad) • Never intended for outside use
  16. 16. sun.misc.Unsafe - What you (don’t) know • Internal class (sun.misc Package) • Used inside the JVM / JRE • Used outside as well (good / bad) • Never intended for outside use
  17. 17. sun.misc.Unsafe - What you (don’t) know • Internal class (sun.misc Package) • Used inside the JVM / JRE • Used outside as well (good / bad) • Never intended for outside use • Used by popular: • Applications • Frameworks • Libraries
  18. 18. MapDB Netty Hazelcast Cassandra Mockito EasyMock JMock Scala Spock Robolectric Grails Gson Neo4j Apache Ignite Apache Spark Apache Kafka Apache Wink Apache Storm Apache Flink Apache Continuum Zookeeper Dropwizard Metrics (AOP) Kryo Byte Buddy Hibernate Liquibase Spring Framework Ehcache OrientDB Chronicle Apache Hadoop Apache HBase GWT Disruptor JRuby AkkaAgrona Aeron Simple Binary Encoding XRebel Presto jol ActivePivot LWJGL XAP XStream CapLogic WildFly Infinispan
  19. 19. MapDB Netty Hazelcast Cassandra Mockito EasyMock JMock Scala Spock Robolectric Grails Gson Neo4j Apache Ignite Apache Spark Apache Kafka Apache Wink Apache Storm Apache Flink Apache Continuum Zookeeper Dropwizard Metrics (AOP) Kryo Byte Buddy Hibernate Liquibase Spring Framework Ehcache OrientDB Chronicle Apache Hadoop Apache HBase GWT Disruptor JRuby AkkaAgrona Aeron Simple Binary Encoding XRebel Presto jol ActivePivot LWJGL XAP XStream CapLogic WildFly Infinispan
  20. 20. sun.misc.Unsafe is only supported on HotSpot JVMs anyways, isn’t it?
  21. 21. sun.misc.Unsafe is only supported on HotSpot JVMs anyways, isn’t it? No!
  22. 22. Language URL sun.misc.Unsafe Avian C++ https://github.com/ReadyTalk/avian Yes BicaVM JavaScript https://github.com/nurv/BicaVM No Cacao C http://www.cacaojvm.org Yes Excelsior JVM C / C++ ? http://www.excelsiorjet.com Yes Dalvik / ART / Android C / C++ https://source.android.com/source/index.html Yes Graal mainly Java http://openjdk.java.net/projects/graal Yes GCJ C / C++ https://gcc.gnu.org/java Yes HaikuVM C http://haiku-vm.sourceforge.net No IBM J9 C / C++ ? http://www.ibm.com/developerworks/java/jdk/index.html Yes IcedTea C / C++ http://icedtea.classpath.org/wiki/Main_Page Yes IKVM.NET C# http://www.ikvm.net Yes Jamiga C https://sourceforge.net/projects/jamiga2 No JamVM C http://jamvm.sourceforge.net Yes JatoVM C http://jatovm.org Yes JikesRVM C microkernel, Java http://www.jikesrvm.org Yes JNode C microkernel, Java http://www.jnode.org Yes JVM.go Go https://github.com/zxh0/jvm.go Yes JX C http://www4.cs.fau.de/Projects/JX/index.html No Kaffe C https://github.com/kaffe/kaffe Yes NanoVM C http://harbaum.org/till/nanovm/index.shtml No OpenJDK / Oracle / Zulu C / C++ http://openjdk.java.net Yes RoboVM C / C++ / ObjC https://robovm.com Yes SAPJVM C / C++ ? http://help.sap.com/saphelp_nwce10/helpdata/en/47/ dc90b4ef17452289f9128b8c2bbd77/content.htm Yes Waratek Multitenant JVM C / C++ ? http://www.waratek.com Yes Zing JVM C / C++ ? https://www.azul.com/products/zing Yes
  23. 23. Use Cases - The Good Ones!
  24. 24. Use Cases - The Good Ones! • Low Latency, GC Overhead
  25. 25. Use Cases - The Good Ones! • Low Latency, GC Overhead Caution: Overly simplified! Unsafe unsafe = findUnsafe();
 long baseAddress = unsafe.allocateMemory(8); 
 class Point {
 long offsetX = 0;
 long offsetY = 4;
 
 int getX(long baseAddress) { return unsafe.getInt(baseAddress + offsetX); } 
 int getY(long baseAddress) { return unsafe.getInt(baseAddress + offsetY); }
 }
  26. 26. Use Cases - The Good Ones! • Low Latency, GC Overhead • Fast (de-)serialization
  27. 27. Use Cases - The Good Ones! • Low Latency, GC Overhead • Fast (de-)serialization // Deserialization public Object readObject(InputStream is) {
 SomeType element = unsafe.allocateInstance(SomeType.class);
 element.deserializeValues(is);
 return element;
 }
  28. 28. Use Cases - The Good Ones! • Low Latency, GC Overhead • Fast (de-)serialization • 64bit Memory regions
  29. 29. Use Cases - The Good Ones! • Low Latency, GC Overhead • Fast (de-)serialization • 64bit Memory regions long baseAddress = unsafe.allocateMemory(Long.MAX_VALUE);
 unsafe.putInt(baseAddress + Long.MAX_VALUE - 4, Integer.MAX_VALUE);
  30. 30. Use Cases - The Good Ones! • Low Latency, GC Overhead • Fast (de-)serialization • 64bit Memory regions • Atomic memory operations
  31. 31. Use Cases - The Good Ones! • Low Latency, GC Overhead • Fast (de-)serialization • 64bit Memory regions • Atomic memory operations unsafe.compareAndSwapInt(this, offsetField, oldValue, newValue);
 unsafe.compareAndSwapLong(this, offsetField, oldValue, newValue);
 unsafe.compareAndSwapObject(this, offsetField, oldObject, newObject);
  32. 32. Use Cases - The Good Ones! • Low Latency, GC Overhead • Fast (de-)serialization • 64bit Memory regions • Atomic memory operations • Efficient memory layout
  33. 33. Use Cases - The Good Ones! • Low Latency, GC Overhead • Fast (de-)serialization • 64bit Memory regions • Atomic memory operations • Efficient memory layout class Point {
 long offsetX = 0;
 long offsetY = 4;
 } offsetX offsetY
  34. 34. Use Cases - The Good Ones! • Low Latency, GC Overhead • Fast (de-)serialization • 64bit Memory regions • Atomic memory operations • Efficient memory layout • Fast field / memory access
  35. 35. Use Cases - The Good Ones! • Low Latency, GC Overhead • Fast (de-)serialization • 64bit Memory regions • Atomic memory operations • Efficient memory layout • Fast field / memory access long versionFieldOffset = unsafe.objectFieldOffset(versionField);
 
 long version = unsafe.getLong(this, versionFieldOffset);
 
 unsafe.putLong(this, versionFieldOffset, 10L);
  36. 36. Use Cases - The Good Ones! • Low Latency, GC Overhead • Fast (de-)serialization • 64bit Memory regions • Atomic memory operations • Efficient memory layout • Fast field / memory access • Access to array elements with volatile semantics
  37. 37. Use Cases - The Good Ones! • Low Latency, GC Overhead • Fast (de-)serialization • 64bit Memory regions • Atomic memory operations • Efficient memory layout • Fast field / memory access • Access to array elements with volatile semantics long base = unsafe.arrayBaseOffset(int[].class);
 long index = unsafe.arrayIndexScale(int[].class);
 
 unsafe.getIntVolatile(array, base + (index * 3));
  38. 38. Use Cases - The Good Ones! • Low Latency, GC Overhead • Fast (de-)serialization • 64bit Memory regions • Atomic memory operations • Efficient memory layout • Fast field / memory access • Access to array elements with volatile semantics • Custom memory fences
  39. 39. Use Cases - The Good Ones! • Low Latency, GC Overhead • Fast (de-)serialization • 64bit Memory regions • Atomic memory operations • Efficient memory layout • Fast field / memory access • Access to array elements with volatile semantics • Custom memory fences unsafe.fullFence(); 
 unsafe.storeFence(); 
 unsafe.loadFence();
  40. 40. Use Cases - The Good Ones! • Low Latency, GC Overhead • Fast (de-)serialization • 64bit Memory regions • Atomic memory operations • Efficient memory layout • Fast field / memory access • Access to array elements with volatile semantics • Custom memory fences • Fast interaction with native code
  41. 41. Use Cases - The Good Ones! • Low Latency, GC Overhead • Fast (de-)serialization • 64bit Memory regions • Atomic memory operations • Efficient memory layout • Fast field / memory access • Access to array elements with volatile semantics • Custom memory fences • Fast interaction with native code long addr = unsafe.allocateMemory(50);
 copyBytes(addr, byteArray);
 nativeCall(addr);
  42. 42. Get Access
  43. 43. Get Access Easy One (not working outside the JRE / JDK) Unsafe unsafe = Unsafe.getUnsafe();
  44. 44. Get Access The Ugly One 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);
 }
 }
  45. 45. Get Access The Working One (at least for more than just HotSpot) private 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");
 }
 });
 }
 }
  46. 46. Get Access The Tricky One private 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);
 }
 }
  47. 47. Get Access Does Any Of This Feel Right?
  48. 48. Weird! No!
  49. 49. WAAAAAT!?!? No!
  50. 50. 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 http://mail.openjdk.java.net/pipermail/openjfx-dev/2015-April/017028.html
  51. 51. 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 http://mail.openjdk.java.net/pipermail/openjfx-dev/2015-April/017028.html
  52. 52. 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 http://mail.openjdk.java.net/pipermail/openjfx-dev/2015-April/017028.html
  53. 53. 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 http://mail.openjdk.java.net/pipermail/openjfx-dev/2015-April/017028.html
  54. 54. Oracle created a new Taskforce
  55. 55. Oracle created a new Taskforce K.U.T.T. - Kill Unsafe To Total death
  56. 56. 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 http://mail.openjdk.java.net/pipermail/openjfx-dev/2015-April/017028.html
  57. 57. So What’s Coming?
  58. 58. private 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; } } } Atomic Updates
  59. 59. Atomic Updates private final AtomicLong version = new AtomicLong(0); public long increment() { return version.incrementAndGet(); }
  60. 60. Atomic Updates 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);
 }
  61. 61. 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);
 }
  62. 62. Atomic Updates public static VarHandle findVersionVarHandle() {
 try {
 return MethodHandles.lookup().
 findFieldVarHandle(Record.class, "version", long.class);
 
 } catch (Exception e) {
 throw new Error(e);
 }
 }
  63. 63. Memory Management public long memory() {
 long address = UNSAFE.allocateMemory(8); 
 UNSAFE.putLong(address, Long.MAX_VALUE); 
 return UNSAFE.getLong(address);
 }
  64. 64. Memory Management public long memory() {
 ByteBuffer byteBuffer = ByteBuffer.allocateDirect(8);
 
 byteBuffer.putLong(0, Long.MAX_VALUE);
 
 return byteBuffer.getLong(0);
 }
  65. 65. 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);
 }
  66. 66. Memory Management public long memory() {
 MemoryRegion region = MemoryRegion.allocateNative
 ("myname", MemoryRegion.UNALIGNED, Long.MAX_VALUE);
 
 VarHandle regionView = MethodHandles.
 memoryRegionViewVarHandle(long[].class, true); 
 regionView.set(region, 0, Long.MAX_VALUE); 
 return regionView.get(region, 0);
 }
  67. 67. Memory Management public long memory() {
 MemoryRegion region = MemoryRegion.allocateNative
 ("myname", MemoryRegion.UNALIGNED, Long.MAX_VALUE);
 
 VarHandle regionView = MethodHandles.
 memoryRegionViewVarHandle(long[].class, true); 
 regionView.set(region, 0, Long.MAX_VALUE); 
 return regionView.get(region, 0);
 }
  68. 68. Memory Management 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();
 }
 }
  69. 69. Memory Management
  70. 70. Deserialization private static final Unsafe UNSAFE = findUnsafe();
 
 private static final long VALUE_OFFSET = findValueOffset();
 
 public String deserializeString() throws Exception {
 char[] chars = readCharsFromStream();
 String allocated = (String) UNSAFE.allocateInstance(String.class);
 UNSAFE.putObjectVolatile(allocated, VALUE_OFFSET, chars);
 return allocated;
 }
  71. 71. Deserialization public String deserializeString() throws Exception {
 char[] chars = readCharsFromStream().freeze();
 
 ReflectionFactory reflectionFactory =
 ReflectionFactory.getReflectionFactory();
 
 Constructor<String> constructor = reflectionFactory
 .newConstructorForSerialization(String.class, char[].class);
 
 return constructor.newInstance(chars);
 }
  72. 72. Interoperability extern c {
 JNIEXPORT int JNICALL
 Java_ProcessIdentifier_getProcessId(JNIEnv *, jobject);
 }
 
 JNIEXPORT int JNICALL
 Java_ProcessIdentifier_getProcessId(JNIEnv *env, jobject thisObj) {
 return getpid();
 }
 
 public class ProcessIdentifier {
 static {
 System.loadLibrary("processidentifier");
 }
 
 public native void talk();
 }
  73. 73. Interoperability interface LibC {
 void getpid();
 }
 
 public int call() {
 LibC c = LibraryLoader.create(LibC.class).load("c");
 return c.getpid();
 }
  74. 74. Interoperability public void call() { MethodType intType = MethodType.methodType(int.class); 
 MethodHandle handle = MethodHandles
 .findNative(null, “getpid”, intType); 
 return (int) handle.invokeExact();
 }
  75. 75. Value Types value class Point {
 final int x;
 final int y;
 }
 
 // Create a Point instance
 Point point = makeValue(1, 2);
  76. 76. Value Types int[] values = new int[2];
 int x = values[0];
 int y = values[1];
  77. 77. Value Types int[] values = new int[2];
 int x = values[0];
 int y = values[1]; Stack var X var Y
  78. 78. Value Types int[] values = new int[2];
 int x = values[0];
 int y = values[1]; Stack var X var Y Stack Allocation!
  79. 79. Specialized Generics class Box<any T> {
 void set(T element) { ... }; 
 T get() { ... };
 }
  80. 80. Specialized Generics class Box<any T> {
 void set(T element) { ... }; 
 T get() { ... };
 } Box<int> Box${T=int}.class
 Box<String> Box${T=java.lang.String}.class
 Box<RandomClass> Box${T=RandomClass}.class
  81. 81. Specialized Generics public void generics() {
 Box<int> intBox = new Box<>();
 intBox.set(1);
 int intValue = intBox.get();
 
 Box<String> stringBox = new Box<>();
 stringBox.set("hello");
 String stringValue = stringBox.get();
 
 Box<RandomClass> box = new Box<>();
 box.set(new RandomClass());
 RandomClass value = box.get();
 }
  82. 82. Arrays 2.0 int[] values = new int[Long.MAX_VALUE];
  83. 83. Arrays 2.0 int[] values = new int[Long.MAX_VALUE]; Arrays.chop(T[] a, int newlength);
  84. 84. Arrays 2.0 int[] values = new int[Long.MAX_VALUE]; Arrays.chop(T[] a, int newlength); Box<String>[] ... = new Box<String>[];
  85. 85. Arrays 2.0 int[] values = new int[Long.MAX_VALUE]; Arrays.chop(T[] a, int newlength); Box<int>[] ... = new Box<int>[];
  86. 86. 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();
  87. 87. 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(); Point[] points = new Point[3]; Stack var X var Y var X var Y var X var Y points[0] points[1] points[2]
  88. 88. Cleaner API Who knows the Cleaner API? You should - it’s around since Java 1.4 ;-)
  89. 89. Cleaner API package 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)); } }
  90. 90. Cleaner API public selfCleaning() {
 try(AutoCleaning autoCleaning : new AutoCleaning()) {
 // do your thing here
 }
 }
  91. 91. Cleaner API public 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(); } }
  92. 92. More exciting stuff upcoming…
  93. 93. Class Dynamic
  94. 94. Class Dynamic •Templating functionality
  95. 95. Class Dynamic •Templating functionality •Aspect-like approach
  96. 96. Class Dynamic •Templating functionality •Aspect-like approach •Group common functionality
  97. 97. Class Dynamic •Templating functionality •Aspect-like approach •Group common functionality •Enhanced Proxies
  98. 98. Class Dynamic •Templating functionality •Aspect-like approach •Group common functionality •Enhanced Proxies R methodName(ARGS) {
 synchronized (this) {
 underlying.methodName(ARGS);
 }
 } Collections::sychronizedMap
  99. 99. 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");
 }
  100. 100. Class Dynamic •Templating functionality •Aspect-like approach •Group common functionality •Enhanced Proxies Your Use Case!
  101. 101. SpinWait Hints
  102. 102. SpinWait Hints Hints the JVM that a busy spin’s upcoming
  103. 103. SpinWait Hints Hints the JVM that a busy spin’s upcoming JVM CAN intrinsify to use a WAIT opcode for the specific platform / CPU
  104. 104. SpinWait Hints Hints the JVM that a busy spin’s upcoming JVM CAN intrinsify to use a WAIT opcode for the specific platform / CPU No-Op implementation for non supported CPUs
  105. 105. SpinWait Hints Hints the JVM that a busy spin’s upcoming JVM CAN intrinsify to use a WAIT opcode for the specific platform / CPU No-Op implementation for non supported CPUs while (!shutdown) {
 while (queue.length == 0) {
 // Hint the JVM to intrinsify wait
 // opcode otherwise busy spin 
 Thread.onSpinWait();
 }
 consume(queue);
 }
  106. 106. What Else? No idea! A lot is changing now. Java / JVM will be different.
  107. 107. What Else? No idea! A lot is changing now. Java / JVM will be different. Don’t forget about Jigsaw, test your application with Java 9 EA builds! https://jdk9.java.net/jigsaw/
  108. 108. Questions? github.com/noctarius @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/
  109. 109. 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

×