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

时间:2014-08-10 23:46:50

标签: java nullpointerexception jvm unsafe

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段错误还是toObject(BOGUS_VALUE)总是会失败NullPointerException(可以被捕获)?

我相信你们大多数人都知道,Unsafe文件充其量只是参差不齐。

1 个答案:

答案 0 :(得分:3)

我在尝试检索丢失的对象之前添加了一些可能导致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

您可能不再指向可被视为对象的地址。它是Unsafe