我想用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());
}
}
}
运行结果如图所示:
找到原因了,java compressed oops的地址长度是32位,不是64位,并且地址编码方式与oops也不同,所以会报错
换本地java编译器,你这是不是用的工具自带的编译器