SeaTalks
SeaTalks
采纳率100%
2016-10-27 09:24 阅读 1.0k
已采纳

使用unsafe获取对象出错

20

我想用unsafe去allocate一块内存,然后在里面创建一个数组对象,然后等到用到的时候再取出来。

我写的Demo如下,但是总是报错,哪位大牛能帮忙解决一个,小弟不胜感激!!!


public class Test {

    private static int byteArrayBaseOffset;

    private static Unsafe unsafe;

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        try{
            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            unsafe = (Unsafe) theUnsafe.get(null);

            int[] test1 = new int[5];
            test1[0] =1 ;
            test1[1] =2;
            int[][] helper = new int[1][1];
            helper[0] = test1;
            @SuppressWarnings("restriction")
            int offset = unsafe.arrayBaseOffset(int[][].class);
            System.out.println("offset is :"+offset);
            long loc = unsafe.getLong(helper,offset);
            System.out.println("the address of test1 : " + loc);

            long baseAddress = unsafe.allocateMemory(100);
            System.out.println("baseAddress is :"+baseAddress);
            int headersize = unsafe.arrayBaseOffset(int[].class);

            //copy the header of test1 and the first element to allocated memory
            for(int i =0;i<headersize+4;i++){
                unsafe.putByte(baseAddress+i, unsafe.getByte(test1, i));
            }


            Object[] array = new Object[1];
            int baseOffSet = unsafe.arrayBaseOffset(Object[].class);
            System.out.println("baseOffset of a array is :"+baseOffSet);

            //put the pointer of test1 into array[0] , it equals to "array[0] = test1;"
            unsafe.putLong(array, baseOffSet, loc); 
            System.out.println("the first element of test1 :"+ ((int[])unsafe.getObject(array, baseOffSet))[0]);

            //put the pointer of int array instance which we created in allocated memory into array[0]
            unsafe.putLong(array, baseOffSet, baseAddress);
            int[] t2 = (int[]) unsafe.getObject(array, baseOffSet);
            System.out.println("the first elment of t2:"+t2[0]);

            unsafe.freeMemory(baseAddress);
        }catch(SecurityException s){
            System.out.println("Security Exception occurred,message is :" + s.getMessage());
        }catch(NoSuchFieldException n){
            System.out.println("NoSuchField Exception occurred,message is :" + n.getMessage());
        }catch(IllegalArgumentException i){
            System.out.println("Illegal argument Exception occurred,message is :" + i.getMessage());
        }catch(IllegalAccessException ia){
            System.out.println("Illegal access Exception occurred,message is :" + ia.getMessage());
        }
    }

}

运行结果如图所示:图片说明

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

2条回答 默认 最新

  • 已采纳
    SeaTalks SeaTalks 2016-10-28 08:23

    找到原因了,java compressed oops的地址长度是32位,不是64位,并且地址编码方式与oops也不同,所以会报错

    点赞 评论 复制链接分享
  • qq_23113827 qq_23113827 2016-10-27 14:16

    换本地java编译器,你这是不是用的工具自带的编译器

    点赞 评论 复制链接分享

相关推荐