java-这个(不安全的)代码会使JVM崩溃吗?

here稍作修改:

import sun.misc.Unsafe;
import java.lang.reflect.*;

public class K {
    private static Unsafe unsafe;
    private static int fieldOffset;
    private static K instance = new K();

    static {
        try {
            Field f = Unsafe.class.getDeclaredField("theUnsafe");
            f.setAccessible(true);

            unsafe = (Unsafe) f.get(null);

            fieldOffset = unsafe.fieldOffset(K.class.getDeclaredField("obj"));
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    private Object obj;

    public synchronized static long toAddress(int o) {
        instance.obj = o;
        return unsafe.getLong(instance, fieldOffset);
    }

    public synchronized static Object toObject(long address) {
        unsafe.putLong(instance, fieldOffset, address);
        return instance.obj;
    }

    public static void main(String[] args) {
        int x = 20;

        System.err.println("x was = " + x);
        long addr = toAddress(x);
        System.err.println("&x = " + addr);
        x = 70;
        System.out.println("x is now " + x);
        long newAddr = toAddress(x);
        System.err.println("new (&x) = " + newAddr);

        System.out.println("Previous value of x is " + toObject(addr)); // !!!
    }
}

特别是,我担心标有!!!的行.如果原始x被垃圾回收,则其地址可能毫无价值.

我的问题是,JVM segfault还是toObject(BOGUS_VALUE)总是会由于NullPointerException而失败(可以捕获)?

如我所知,大多数人都知道,不安全文档最多是斑点.

解决方法:

在尝试检索丢失的对象之前,我添加了一些可能导致GC的代码.

for (int i = 0; i < 1000000; i ++) {
    new Object().toString();
}
System.out.println("Previous value of x is " + toObject(addr).getClass()); // !!!

并得到了

#  SIGSEGV (0xb) at pc=0x000000010e627c46, pid=49698, tid=6403

您所拥有的地址可能不再指向可以被视为对象的对象.这是不安全的.

上一篇:并发编程之原子操作Atomic&Unsafe


下一篇:ubuntu 固定静态IP