unsafe: халява закончилась?2015.secrus.org/2015/files/027_fyodorov.pdf · 4...

Post on 03-Aug-2020

5 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Unsafe:халявазакончилась?

АлексейФедоров,Одноклассники/ JUG.ru

2

Что такое Unsafe

• Оченьспециальныйобъект• СуществуетсJDK1.4 — уже15лет• НуженвClassLibrary,чтобыоттудадергать JVM

“AVM/libraryinterface,designedstrictlyforusewithintheJDK”

MarkReinhold,JavaPlatformArchitectJVMLS2015

3

Что такое Unsafe

• Оченьспециальныйобъект• СуществуетсJDK1.4 — уже15лет• НуженвClassLibrary,чтобыоттудадергать JVM

4

Используется в разных частях JDK

• 1.4— Reflection,Serialization,NIO• 1.5— JSR166(atomics,locks),CORBA,AWT• 6.0— JSR166(CopyOnWriteArrayList etc.)• 7 — JSR166(ForkJoin etc.),BigDecimal,java.lang.invoke• 8— JSR166(много!),MacOSXobjectiveCbridge

5

sun.misc.Unsafe

• Лежитвприватномпакетеsun.misc- раньшевSunJDK- потомвOpenJDK- перекочевалвOracleJDK

6

А что на других JDK?

7

А что на других JDK?

public final class Unsafe {

static {registerNatives();Reflection.registerMethodsToFilter(Unsafe.class, "getUnsafe");…

}

private Unsafe() {}

private static final Unsafe theUnsafe = new Unsafe();

@CallerSensitivepublic static Unsafe getUnsafe() {

Class cc = Reflection.getCallerClass();if (cc.getClassLoader() != null)

throw new SecurityException("Unsafe");return theUnsafe;

}

9

Как получить Unsafe

public static final Unsafe UNSAFE = getUnsafe();

private static Unsafe getUnsafe() {try {

Field f = Unsafe.class.getDeclaredField("theUnsafe");f.setAccessible(true);return (Unsafe) f.get(null);

} catch (Exception e) {throw new RuntimeException(e);

}}

10

И всё???

ПоумолчаниюSecutiry ManagerвJavaвыключен!

11

И всё???

$ java -Djava.security.manager

java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.sun.misc")

ПоумолчаниюSecutiry ManagerвJavaвыключен!

12

«Тебя предупреждали»

$ javac Test.java

Test.java:2: warning: Unsafe is internal proprietary API and may be removed in a future releaseimport sun.misc.Unsafe;

^

13

«Да мне пофиг!»

$ javac Test.java

Test.java:2: warning: Unsafe is internal proprietary API and may be removed in a future releaseimport sun.misc.Unsafe;

^

$ javac -XDignore.symbol.file Test.java

ЧтоумеетUnsafe?

package cee.secr.misc;

public class MyUnsafe {

public native int getInt(long address);

#include <jni.h>

JNIEXPORT jint JNICALLJava_snow_misc_MyUnsafe(JNIEnv* env, jobject myUnsafe,

jlong address) {return *(jint*)address;

}

Create stack frameMove arguments according to ABI

Wrap objects into JNI handlesObtain JNIEnv* and jclass

Trace method_entryLock if synchronized

Lazy lookup and linkingin_java à in_native thread transition

Call the native functionCheck for safepoint

Switch state to in_javaUnlock if synchronized

Notify method_exitUnwrap result, reset JNI handles block

Handle exceptionsRemove stack frame

Сколько стоит JNI

18

Intrinsics

• Большинствометодов— intrisics:- getInt —> mov- compareAndSwapInt—> cmpxchg

CAS// nativepublic final native boolean compareAndSwapInt(

Object o, long offset, int expected, int x);

//non-nativepublic final int getAndAddInt(

Object o, long offset, int delta) {int v;do {

v = getIntVolatile(o, offset);} while (!compareAndSwapInt(o, offset, v, v + delta));return v;

}

AtomicInteger — i.getAndAdd(5)

loop:mov 0xc(%r10),%eaxmov %eax,%r11dadd $0x5,%r11dlock cmpxchg %r11d,0xc(%r10)sete %r11bmovzbl %r11b,%r11dtest %r11d,%r11dje loop

JDK 7u72 JDK 8u66

lock addl $0x5,0xc(%r10)

83

4615 11

132105

45 43

1 2 3 4

ops/μ

s

threads

-XX:+PrintAssembly

Usecases

22

Off-heap Collections

• Lists,sets,maps- Largecapacity>2GB- PredictableGCpauses- Noheapfragmentation- Datalocality

23Data locality

Key

ValueKey

Value

Map.Entry Off-heaplayout

a b c a b c a b c

24

I/O and persistence

• Persistentcachesandstorages- Memory-mappedfiles(64-bit)- Sharedmemory

• CooperationwithOS- Pointerarithmetic,alignment- mlock,madvise etc.

25

IPC, Messaging

• Concurrentoff-heapbuffersandqueues• High-performancemessaging- Disruptor- Aeron:6Mmsg/s

• Shareddatastructures- ChronicleMap

УдалениеUnsafe

27

Тактика действий в случие удаления Unsafe

• Переписатькускикода- JNI- Reflection- NIO- etc.

28

Тактика действий в случие удаления Unsafe

• Переписатькускикода- JNI- Reflection- NIO- etc.

• Какдействовать1. Новыйlayer:wrapper надUnsafe2. ЗаменитьнаwrapperнадpublicAPI

Беда1:PerformanceDegradation

Cassandra

Netty

Guava

Hazlecast

Mockito

GWT

HadoopZookeeper

Kafka

Gson

Neo4j

Grails

Spring

Disruptor

JRuby

Scala

Akka

Cassandra

Netty

Guava

Hazlecast

Mockito

GWT

HadoopZookeeper

Kafka

Gson

Neo4j

Grails

Spring

JRuby

Scala

Akka

UnsafeDisruptor

Беда2:Transitivelock-in

33

Как так получилось?

$ javac Test.java

Test.java:2: warning: Unsafe is internal proprietary API and may be removed in a future releaseimport sun.misc.Unsafe;

^

34

Как так получилось?

Слишкоммалоевангелизма,Oracle!

$ javac Test.java

Test.java:2: warning: Unsafe is internal proprietary API and may be removed in a future releaseimport sun.misc.Unsafe;

^

Какразвиваласьситуация

36

Хронология событий

• JEP200:TheModularJDK

37

Хронология событий

• JEP200:TheModularJDK- MarkReinholdвыступилна Devoxx 2014

38

Хронология событий

• JEP200:TheModularJDK- MarkReinholdвыступилна Devoxx 2014

• Постна blog.dripstat.com

39

Хронология событий

• JEP200:TheModularJDK- MarkReinholdвыступилна Devoxx 2014

• Постна blog.dripstat.com• ChrisEngelbert изHazelcast началдискуссию

40

Хронология событий

• JEP200:TheModularJDK- MarkReinholdвыступилна Devoxx 2014

• Постна blog.dripstat.com• ChrisEngelbert изHazelcast началдискуссию• ОбсуждениенаJСrete

41

Хронология событий

• JEP200:TheModularJDK- MarkReinholdвыступилна Devoxx 2014

• Постна blog.dripstat.com• ChrisEngelbert изHazelcast началдискуссию• ОбсуждениенаJCrete• MarkReinholdвыступилнаJVMLS- всенемногоуспокоились

42

Хронология событий

• JEP200:TheModularJDK- MarkReinholdвыступилна Devoxx 2014

• Постна blog.dripstat.com• ChrisEngelbert изHazelcast началдискуссию• ОбсуждениенаJCrete• MarkReinholdвыступилнаJVMLS- всенемногоуспокоились

• JEP260:EncapsulateMostInternalAPIs

43

План замены Unsafe на public API

• ReplacementinJDK8à hideinJDK9- sun.misc.BASE64Encoderetc.- Availableviacommand-lineflag

• NoreplacementinJDK8à availableoutside- sun.misc.Unsafe,sun.reflect.ReflectionFactory- sun.misc.Cleaner,sun.misc.SignalHandler

• ReplacementinJDK9à hideinJDK9,removeinJDK10

Чтоприходитназамену

JEP193:VarHandlesExpectedinJava9

class Queue {int size;...

}

VarHandle queueSize = VarHandles.lookup().findFieldHandle(Queue.class, "size", int.class);

queueSize.addAndGet(10);

46

• get, getVolatile, getAcquire, getOpaque• set, setVolatile, setRelease, setOpaque• compareAndSet, compareAndExchangeVolatile• compareAndExchangeAcquire, compareAndExchangeRelease• weakCompareAndSet, weakCompareAndSetAcquire, weakCompareAndSetRelease

• getAndSet, getAndAdd, addAndGet

VarHandle handle = VarHandles.arrayElement(int[].class)

VarHandle viewHandle = VarHandles.arrayElementViewHandle(byte[].class, long[].class, true);

47

ByteBuffer byteBuffer = ByteBuffer.allocateDirect(8);VarHandle bufferView =

VarHandles.byteBufferViewHandle(long[].class, true);

MemoryRegion region = MemoryRegion.allocateNative("myname", MemoryRegion.UNALIGNED, Long.MAX_VALUE);

VarHandle regionView =VarHandles.memoryRegionViewHandle(long[].class, true);

regionView.set(region, 0, Long.MAX_VALUE);return regionView.get(region, 0);

48

Итоги

• Вендор услышалсообществоиизменилпланы- Вендор готовидальшеслушать- Сообществопредставляетсобойсилу,занимэкосистема

49

Итоги

• Вендор услышалсообществоиизменилпланы- Вендор готовидальшеслушать- Сообществопредставляетсобойсилу,занимэкосистема

• Unsafeвсе-такивыпилят- Нопостепенно,втечениенесколькихлет

50

Development @ Одноклассники

• TechBlog- http://habrahabr.ru/company/odnoklassniki

• Opensource- https://github.com/odnoklassniki

• Career- http://v.ok.ru

БлагодарюАндреяПаньгина

@AndreyPangin

Вопросыиответы

Спасибозавнимание!

@23derevoalexey.fyodorov@corp.mail.ru

top related