Why does sun.misc.Unsafe exist, and how can it be used in the real world?
examples
-
VM "intrinsification." ie CAS (Compare-And-Swap) used in Lock-Free Hash Tables eg:sun.misc.Unsafe.compareAndSwapInt it can make real JNI calls into native code that contains special instructions for CAS
read more about CAS here http://en.wikipedia.org/wiki/Compare-and-swap
The sun.misc.Unsafe functionality of the host VM can be used to allocate uninitialized objects and then interpret the constructor invocation as any other method call.
One can track the data from the native address.It is possible to retrieve an object’s memory address using the java.lang.Unsafe class, and operate on its fields directly via unsafe get/put methods!
Compile time optimizations for JVM. HIgh performance VM using "magic", requiring low-level operations. eg: http://en.wikipedia.org/wiki/Jikes_RVM
Allocating memory, sun.misc.Unsafe.allocateMemory eg:- DirectByteBuffer constructor internally calls it when ByteBuffer.allocateDirect is invoked
Tracing the call stack and replaying with values instantiated by sun.misc.Unsafe, useful for instrumentation
sun.misc.Unsafe.arrayBaseOffset and arrayIndexScale can be used to develop arraylets,a technique for efficiently breaking up large arrays into smaller objects to limit the real-time cost of scan, update or move operations on large objects
http://robaustin.wikidot.com/how-to-write-to-direct-memory-locations-in-java
more on references here - http://bytescrolls.blogspot.com/2011/04/interesting-uses-of-sunmiscunsafe.html
Just from running a search in some code search engine I get the following examples:
- Java Object Notation - use it for more efficient array processing, quoting the javadoc
Simple class to obtain access to the {@link Unsafe} object. {@link Unsafe} * is required to allow efficient CAS operations on arrays. Note that the versions in {@link java.util.concurrent.atomic}, such as {@link java.util.concurrent.atomic.AtomicLongArray}, require extra memory ordering guarantees which are generally not needed in these algorithms and are also expensive on most processors.
- SoyLatte - java 6 for osx javadoc excerpt
/** Base class for sun.misc.Unsafe-based FieldAccessors for static fields. The observation is that there are only nine types of fields from the standpoint of reflection code: the eight primitive types and Object. Using class Unsafe instead of generated bytecodes saves memory and loading time for the dynamically-generated FieldAccessors. */
- SpikeSource
/* FinalFields that are sent across the wire .. how to unmarshall and recreate the object on the receiving side? We don't want to invoke the constructor since it would establish values for final fields. We have to recreate the final field exactly like it was on the sender side. The sun.misc.Unsafe does this for us. */
There are many other examples, just follow the above link...
Interesting, I'd never even heard of this class (which is probably a good thing, really).
One thing that jumps to mind is using Unsafe#setMemory to zeroize buffers that contained sensitive information at one point (passwords, keys, ...). You could even do this to fields of "immutable" objects (then again I suppose plain old reflection might do the trick here too). I'm no security expert though so take this with a grain of salt.
Based on a very brief analysis of the Java 1.6.12 library using eclipse for reference tracing, it seems as though every useful functionality of Unsafe
is exposed in useful ways.
CAS operations are exposed through the Atomic* classes. Memory manipulations functions are exposed through DirectByteBuffer Sync instructions (park,unpark) are exposed through the AbstractQueuedSynchronizer which in turn is used by Lock implementations.
Unsafe.throwException - allows to throw checked exception without declaring them.
This is useful in some cases where you deal with reflection or AOP.
Assume you Build a generic proxy for a user defined Interface. And the user can specify which exception is thrown by the implmentation in a special case just by declaring the exception in the interface. Then this is the only way I know, to rise a checked exception in the Dynamic Implementation of the Interface.
import org.junit.Test;
/** need to allow forbidden references! */ import sun.misc.Unsafe;
/**
* Demonstrate how to throw an undeclared checked exception.
* This is a hack, because it uses the forbidden Class {@link sun.misc.Unsafe}.
*/
public class ExceptionTest {
/**
* A checked exception.
*/
public static class MyException extends Exception {
private static final long serialVersionUID = 5960664994726581924L;
}
/**
* Throw the Exception.
*/
@SuppressWarnings("restriction")
public static void throwUndeclared() {
getUnsafe().throwException(new MyException());
}
/**
* Return an instance of {@link sun.misc.Unsafe}.
* @return THE instance
*/
@SuppressWarnings("restriction")
private static Unsafe getUnsafe() {
try {
Field singleoneInstanceField = Unsafe.class.getDeclaredField("theUnsafe");
singleoneInstanceField.setAccessible(true);
return (Unsafe) singleoneInstanceField.get(null);
} catch (IllegalArgumentException e) {
throw createExceptionForObtainingUnsafe(e);
} catch (SecurityException e) {
throw createExceptionForObtainingUnsafe(e);
} catch (NoSuchFieldException e) {
throw createExceptionForObtainingUnsafe(e);
} catch (IllegalAccessException e) {
throw createExceptionForObtainingUnsafe(e);
}
}
private static RuntimeException createExceptionForObtainingUnsafe(final Throwable cause) {
return new RuntimeException("error while obtaining sun.misc.Unsafe", cause);
}
/**
* scenario: test that an CheckedException {@link MyException} can be thrown
* from an method that not declare it.
*/
@Test(expected = MyException.class)
public void testUnsingUnsaveToThrowCheckedException() {
throwUndeclared();
}
}