SeaTalks 2016-10-27 09:24 采纳率: 100%
浏览 1065
已采纳

使用unsafe获取对象出错

我想用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 2016-10-28 08:23
    关注

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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器