[ACCEPTED]-Why does sun.misc.Unsafe exist, and how can it be used in the real world?-unsafe
examples
VM "intrinsification." ie 27 CAS (Compare-And-Swap) used in Lock-Free 26 Hash Tables eg:sun.misc.Unsafe.compareAndSwapInt it 25 can make real JNI calls into native code 24 that contains special instructions for CAS
read 23 more about CAS here http://en.wikipedia.org/wiki/Compare-and-swap
The sun.misc.Unsafe 22 functionality of the host VM can be used 21 to allocate uninitialized objects and then 20 interpret the constructor invocation as 19 any other method call.
One can track the 18 data from the native address.It is possible 17 to retrieve an object’s memory address using 16 the java.lang.Unsafe class, and operate 15 on its fields directly via unsafe get/put 14 methods!
Compile time optimizations for JVM. HIgh 13 performance VM using "magic", requiring 12 low-level operations. eg: http://en.wikipedia.org/wiki/Jikes_RVM
Allocating memory, sun.misc.Unsafe.allocateMemory 11 eg:- DirectByteBuffer constructor internally 10 calls it when ByteBuffer.allocateDirect 9 is invoked
Tracing the call stack and replaying 8 with values instantiated by sun.misc.Unsafe, useful 7 for instrumentation
sun.misc.Unsafe.arrayBaseOffset 6 and arrayIndexScale can be used to develop 5 arraylets,a technique for efficiently breaking 4 up large arrays into smaller objects to 3 limit the real-time cost of scan, update 2 or move operations on large objects
http://robaustin.wikidot.com/how-to-write-to-direct-memory-locations-in-java
more 1 on references here - http://bytescrolls.blogspot.com/2011/04/interesting-uses-of-sunmiscunsafe.html
Just from running a search in some code search 26 engine I get the following examples:
- Java Object Notation - use it for more efficient array processing, quoting the javadoc
Simple 25 class to obtain access to the {@link Unsafe} object. {@link 24 Unsafe} * is required to allow efficient 23 CAS operations on arrays. Note that the versions 22 in {@link java.util.concurrent.atomic}, such 21 as {@link java.util.concurrent.atomic.AtomicLongArray}, require 20 extra memory ordering guarantees which 19 are generally not needed in these algorithms 18 and are also expensive on most processors.
- SoyLatte - java 6 for osx javadoc excerpt
/** Base 17 class for sun.misc.Unsafe-based FieldAccessors 16 for static fields. The observation 15 is that there are only nine types of fields 14 from the standpoint of reflection code: the 13 eight primitive types and Object. Using 12 class Unsafe instead of generated bytecodes 11 saves memory and loading time for the dynamically-generated 10 FieldAccessors. */
- SpikeSource
/* FinalFields that 9 are sent across the wire .. how to unmarshall 8 and recreate the object on the receiving 7 side? We don't want to invoke the constructor 6 since it would establish values for final 5 fields. We have to recreate the final field 4 exactly like it was on the sender side. The 3 sun.misc.Unsafe does this for us. */
There 2 are many other examples, just follow the 1 above link...
Interesting, I'd never even heard of this 9 class (which is probably a good thing, really).
One 8 thing that jumps to mind is using Unsafe#setMemory to zeroize 7 buffers that contained sensitive information 6 at one point (passwords, keys, ...). You 5 could even do this to fields of "immutable" objects 4 (then again I suppose plain old reflection 3 might do the trick here too). I'm no security 2 expert though so take this with a grain 1 of salt.
Based on a very brief analysis of the Java 8 1.6.12 library using eclipse for reference 7 tracing, it seems as though every useful 6 functionality of Unsafe
is exposed in useful ways.
CAS 5 operations are exposed through the Atomic* classes. Memory 4 manipulations functions are exposed through 3 DirectByteBuffer Sync instructions (park,unpark) are 2 exposed through the AbstractQueuedSynchronizer 1 which in turn is used by Lock implementations.
Unsafe.throwException - allows to throw checked exception without 9 declaring them.
This is useful in some cases 8 where you deal with reflection or AOP.
Assume 7 you Build a generic proxy for a user defined 6 Interface. And the user can specify which 5 exception is thrown by the implmentation 4 in a special case just by declaring the 3 exception in the interface. Then this is 2 the only way I know, to rise a checked exception 1 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();
}
}
Class Unsafe
A collection of methods for performing low-level, unsafe 4 operations. Although the class and all methods 3 are public, use of this class is limited 2 because only trusted code can obtain instances 1 of it.
One use of it is in java.util.concurrent.atomic
classes:
For efficient memory copy (faster to copy 6 than System.arraycopy() for short blocks 5 at least); as used by Java LZF and Snappy codecs. They 4 use 'getLong' and 'putLong', which are faster 3 than doing copies byte-by-byte; especially 2 efficient when copying things like 16/32/64 1 byte blocks.
I was recently working on reimplementing 22 the JVM and found that a surprising number 21 of classes are implemented in terms of Unsafe
. The 20 class is mostly designed for the Java library 19 implementers and contains features that 18 are fundamentally unsafe but necessary for 17 building fast primitives. For example, there 16 are methods for getting and writing raw 15 field offsets, using hardware-level synchronization, allocating 14 and freeing memory, etc. It is not intended 13 to be used by normal Java programmers; it's 12 undocumented, implementation-specific, and 11 inherently unsafe (hence the name!). Moreover, I 10 think that the SecurityManager
will disallow access to 9 it in almost all cases.
In short, it mainly 8 exists to allow library implementers access 7 to the underlying machine without having 6 to declare every method in certain classes 5 like AtomicInteger
native. You shouldn't need to use 4 or worry about it in routine Java programming, as 3 the whole point is to make the rest of the 2 libraries fast enough that you wouldn't 1 need that sort of access.
Off-heap collections may be useful for allocating 4 huge amounts of memory and deallocating 3 it immediately after use without GC interference. I 2 wrote a library for working with off-heap arrays/lists 1 based on sun.misc.Unsafe
.
Use it to access and allocate large amounts 38 of memory efficiently, such as in your very 37 own voxel engine! (i.e. Minecraft-style 36 game.)
In my experience, the JVM is often 35 unable to eliminate bounds-checking in place 34 you truly need it. For example, if you're 33 iterating over a large array, but the actual 32 memory access is tucked underneath a non-virtual* method 31 call in the loop, the JVM may still perform 30 a bounds check with each array access, rather 29 than once just before the loop. Thus, for 28 potentially large performance gains, you 27 can eliminate JVM bounds-checking inside 26 the loop via a method which employs sun.misc.Unsafe 25 to access the memory directly, making sure 24 to do any bounds-checking yourself at the 23 correct places. (You are gonna bounds check 22 at some level, right?)
*by non-virtual, I mean the JVM shouldn't have to dynamically resolve whatever your particular method is, because you've correctly guaranteed that class/method/instance are some combination of static/final/what-have-you.
For my home-grown 21 voxel engine, this resulted in a dramatic 20 performance gain during chunk generation 19 and serialization (iow places where I was 18 reading/writing to the entire array at once). Results 17 may vary, but if a lack of bounds-elimination 16 is your problem, then this will fix it.
There 15 are some potentially major problems with 14 this: specifically, when you provide the 13 ability to access memory without bounds-checking 12 to clients of your interface, they will 11 probably abuse it. (Don't forget that hackers 10 can also be clients of your interface... especially 9 in the case of a voxel engine written in 8 Java.) Thus, you should either design your 7 interface in a way such that memory access 6 cannot be abused, or you should be extremely 5 careful to validate user-data before it 4 can ever, ever mingle with your dangerous interface. Considering 3 the catastrophic things a hacker can do 2 with unchecked memory access, it's probably 1 best to take both approaches.
We have implemented huge collections like 5 Arrays,HashMaps,TreeMaps using Unsafe.
And 4 to avoid/minimize the fragmentation, we 3 implemented memory allocator using the concepts 2 of dlmalloc over unsafe.
This helped us to gain 1 the performance in concurrency.
Unsafe.park()
and Unsafe.unpark()
for the construction of custom concurrency 2 control structures and cooperative scheduling 1 mechanisms.
Haven't used it myself, but I suppose if 6 you have a variable that is only occasionally 5 read by more than one thread (so you don't 4 really want to make it volatile) you could 3 use the putObjectVolatile
when writing it in the main thread 2 and readObjectVolatile
when doing the rare reads from other 1 threads.
You need it if you need to replace functionality 7 provided by one of the classes which uses 6 it currently.
This can be custom/faster/more 5 compact serialization/deserialization, a 4 faster/larger buffer/resizable version of 3 ByteBuffer, or adding an atomic variable 2 e.g. one not supported currently.
I have 1 used it for all of these at some time.
The object appears to be availability to 17 work at a lower level than what Java code 16 typically allows for. If you're coding a 15 high level application then the JVM abstracts 14 memory handling and other operations away 13 from the code level so its easier to program. By 12 using the Unsafe library you're effectively 11 completing low-level operations that would 10 typically be done for you.
As woliveirajr 9 stated "random()" uses Unsafe to seed just 8 as many other operations will use the allocateMemory() function 7 included in Unsafe.
As a programmer you probably 6 could get away with never needing this library 5 but having strict control over low-level 4 elements does come in handy (that's why 3 there is still Assembly and (to a lesser 2 extent) C code drifting around in major 1 products)
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.