前几天我偶然发现了一个不安全的包装,它的功能让我感到惊讶。

当然,这个类是没有记录的,但是我想知道是否有一个很好的理由使用它。可能会出现哪些需要使用它的场景?如何在现实场景中使用它?

此外,如果您确实需要它,这难道不表明您的设计可能存在问题吗?

为什么Java包含这个类?


当前回答

堆外集合对于分配大量内存并在使用后立即释放内存而不受GC干扰可能很有用。我基于sun.misc.Unsafe编写了一个用于处理堆外数组/列表的库。

其他回答

使用它来有效地访问和分配大量的内存,例如在您自己的体素引擎中!(例如《我的世界》风格的游戏。)

In my experience, the JVM is often unable to eliminate bounds-checking in place you truly need it. For example, if you're iterating over a large array, but the actual memory access is tucked underneath a non-virtual* method call in the loop, the JVM may still perform a bounds check with each array access, rather than once just before the loop. Thus, for potentially large performance gains, you can eliminate JVM bounds-checking inside the loop via a method which employs sun.misc.Unsafe to access the memory directly, making sure to do any bounds-checking yourself at the correct places. (You are gonna bounds check 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.

对于我自己开发的体素引擎来说,这在块生成和序列化期间(在我同时读取/写入整个数组的低位置)带来了显著的性能提升。结果可能会有所不同,但如果缺乏界限消除是您的问题,那么这将解决它。

There are some potentially major problems with this: specifically, when you provide the ability to access memory without bounds-checking to clients of your interface, they will probably abuse it. (Don't forget that hackers can also be clients of your interface... especially in the case of a voxel engine written in Java.) Thus, you should either design your interface in a way such that memory access cannot be abused, or you should be extremely careful to validate user-data before it can ever, ever mingle with your dangerous interface. Considering the catastrophic things a hacker can do with unchecked memory access, it's probably best to take both approaches.

not safe.park()和not safe.unpark()用于构建自定义并发控制结构和协作调度机制。

不安全的。允许抛出检查异常而不声明它们。

这在处理反射或AOP的某些情况下非常有用。

假设您为用户定义的接口构建了通用代理。在特殊情况下,用户可以通过在接口中声明异常来指定由实现抛出的异常。这是我所知道的唯一方法,在接口的动态实现中引发一个受控异常。

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();
    }
}

有趣的是,我甚至从未听说过这个类(这可能是一件好事,真的)。

我想到的一件事是使用Unsafe#setMemory将包含敏感信息的缓冲区归零(密码、密钥等)。您甚至可以对“不可变”对象的字段执行此操作(然后,我再次假设普通的反射也可以在这里执行此操作)。但我不是安全专家,所以对此持保留态度。

例子

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

更多的参考资料在这里- http://bytescrolls.blogspot.com/2011/04/interesting-uses-of-sunmiscunsafe.html