Why Does Sun.Misc.Unsafe Exist, and How Can It Be Used in the Real World

How unsafe is the use of sun.misc.Unsafe actually?

There are three significant (IMO) issues:

  • The methods in the Unsafe class have the ability to violate runtime type safety, and do other things that can lead to your JVM "hard crashing".

  • Virtually anything that you do using Unsafe could in theory be dependent on internal details of the JVM; i.e. details of how the JVM does things and represents things. These may be platform dependent, and may change from one version of Java to the next.

  • The methods you are using ... or even the class name itself ... may not be the same across different releases, platforms and vendors.

IMO, these amount to strong reasons not to do it ... but that is a matter of opinion.

Now if Unsafe becomes standardised / part of the standard Java API (e.g. in Java 9), then some of the above issues would be moot. But I think the risk of hard crashes if you make a mistake will always remain.

Why is sun.misc.unsafe.Unsafe not in one of the default java.* packages?

Making Unsafe part of the core API, and implementing the JLS are separate issues.

Unsafe is not part of the Java API because it's unsafe, and Oracle didn't want developers to use it.

However, they are well aware 1) that many good developers have used it successfully, and that 2) many bad developers have abused it. So, there is a long term plan to expose the useful features of Unsafe through the core Java platform in a safe, sane, and supportable way.

You can view a presentation from Mark Reinhold that explains in more detail how Unsafe will be migrated and eventually go way.

However, even when Unsafe APIs are moved into some java (or javax) package, providers will still have internal classes and native code to implement those APIs. For example, Oracle might have something like oracle.internal.misc.StillUnsafe with a bunch of native methods in it. This class won't be governed by the JLS; Oracle will be free to implement it how they like and change it when they like. But, with this approach, they would also provide implementations of the core Java APIs that delegate to their internal class.

Declaring the API in a java.* package does not mean that authors of Java runtimes don't have to provide the code to back it up; many Java APIs are abstract and must be given an implementation by a provider.

Is sun.misc.Unsafe become public in JDK9?

Here is a good explanation:

https://adtmag.com/blogs/watersworks/2015/08/java-9-hack.aspx

What to do with sun.misc.Unsafe in Java 9? One side says it's simply
an awful hack from the bad old days that should be gotten rid of; the
other side says its heavy use is responsible for the rise of Java in
the infrastructure space and popular tools still need it. The problem
is, both sides are right.
...

Writing on the OpenJDK mailing list, Reinhold proposed encapsulating
unsupported, internal APIs, including sun.misc.Unsafe, within modules
that define and use them. That proposal is now a formal Java
Enhancement Proposals (JEP). Posted this week, JEP 260 ("Encapsulate
Most Internal APIs") aims to "make most of the JDK's internal APIs
inaccessible by default, but leave a few critical, widely used
internal APIs accessible, until supported replacements exist for all
or most of their functionality."

Short answer: you should NOT use it in any new application you're developing from scratch.

Is sun.misc.Unsafe thread safe?

The methods of Unsafe are not thread safe. You need to synchronize access to data you want to manipulate yourself - as usual. Accessing the instance theUnsafe however is, because the field gets initialized when the class is being loaded (it's static).

Where is sun.misc.Unsafe documented?

There is a nice post about it on mishadoff's blog here.

The class is officially undocumented though.

Removal of sun.misc.Unsafe in Java 9 will break Spring, Hibernate

Mark Reinhold had a talk during JVM Language Summit 2015 titled The Secret History and Tragic Fate of sun.misc.Unsafe. Although these talks have plenty of disclaimers on them, you can see the proposed approach at 10:23, which is described in JEP260.

The general idea is:

  1. replace existing functionality with safer, supported APIs
  2. deprecate the previously existing Unsafe APIs that has been replaced
  3. remove the deprecated code in the next version

Here is some relevant text from JEP260 (taken from October 20th 2015):

In JDK 9 we propose to:

  • Encapsulate all non-critical internal APIs by default: The modules that define them will not export their packages for outside use. (Access to such APIs will be available, as a last resort, via a command-line flag at both compile time and run time, unless those APIs are revised or removed for other reasons.)

  • Encapsulate critical internal APIs for which supported replacements exist in JDK 8, in the same manner and with the same last-resort workaround. (A supported replacement is one that is either part of the Java SE 8 standard (i.e., in a java.* or javax.* package) or else JDK-specific and annotated with @jdk.Exported (typically in a com.sun.* or jdk.* package).)

  • Not encapsulate critical internal APIs for which supported replacements do not exist in JDK 8 and, further, deprecate those which have supported replacements in JDK 9 with the intent to encapsulate them, or possibly even remove them, in JDK 10.


...

Critical internal APIs for which replacements are introduced in JDK 9 will be deprecated in JDK 9 and either encapsulated or removed in JDK 10.

Dealing with 16 bit characters using sun.misc.Unsafe

JavaDoc for Unsafe#allocationMemory says:

Allocates a new block of native memory, of the given size in bytes. The
contents of the memory are uninitialized; they will generally be
garbage
. The resulting native pointer will never be zero, and will be
aligned for all value types. Dispose of this memory by calling #freeMemory , or resize it with #reallocateMemory .

Which means when you put byte there and read char back you get extra byte of garbage.

Using sun.misc.Unsafe to get address of Java array items?

Instead of using an array you can use a ByteBuffer.allocateDirect() direct buffer. This has the address in a field and this address doesn't change for the life of the ByteBuffer. A direct ByteBuffer uses minimal heap space. You can get the address using reflection.


You can use Unsafe to get an address, the problem is that the GC can move it at any time. Objects are not fixed in memory.

In JNI you can use special methods to copy data to/from Java objects to avoid this issue (and others) I suggest you use these if you want to exchange data between Objects with C code.

sun.misc.Unsafe putInt, getInt source

I want to find the source. The Unsafe is implemented by java and native source. So I found the two sources.:

  • OpenJDK8u Unsafe.java
  • OpenJDK8u unsafe.cpp

There is the header file.



Related Topics



Leave a reply



Submit