设为首页 加入收藏

TOP

Java不能操作内存?Unsafe了解一下(四)
2023-08-26 21:11:18 】 浏览:123
Tags:Java 能操作 Unsafe 解一下
n("Unsafe.ARRAY_FLOAT_INDEX_SCALE=" + Unsafe.ARRAY_FLOAT_INDEX_SCALE); System.out.println("Unsafe.ARRAY_DOUBLE_BASE_OFFSET=" + Unsafe.ARRAY_DOUBLE_BASE_OFFSET); System.out.println("Unsafe.ARRAY_DOUBLE_INDEX_SCALE=" + Unsafe.ARRAY_DOUBLE_INDEX_SCALE); System.out.println("Unsafe.ARRAY_OBJECT_BASE_OFFSET=" + Unsafe.ARRAY_OBJECT_BASE_OFFSET); System.out.println("Unsafe.ARRAY_OBJECT_INDEX_SCALE=" + Unsafe.ARRAY_OBJECT_INDEX_SCALE); System.out.println("------------------------------"); // 基本数据数组类型操作 int[] array = new int[] {11, 22, 33}; /* 改变最后一个元素的值,地址的算法就是:基础地址+偏移量,这个偏移量就是类型占用的大小*位置,Unsafe.ARRAY_INT_BASE_OFFSET + (array.length - 1) * Unsafe.ARRAY_INT_INDEX_SCALE */ System.out.println("before put array[2]=" + array[2]); unsafe.putInt(array, (long)Unsafe.ARRAY_INT_BASE_OFFSET + (array.length - 1) * Unsafe.ARRAY_INT_INDEX_SCALE, 100); // 获取最后一个元素的值 System.out.println("after put array[2]=" + array[2]); // 也可以这么获取,使用基础地址+偏移量的方式 System.out.println("after put array[2]=" + unsafe.getInt(array, (long)Unsafe.ARRAY_INT_BASE_OFFSET + (array.length - 1) * Unsafe.ARRAY_INT_INDEX_SCALE)); System.out.println("-------------------"); // Object类型数组操作 Cat[] cats = {new Cat("cat1", 1), new Cat("cat2", 2), new Cat("cat3", 3)}; System.out.println("before put cats[2]=" + cats[2]); unsafe.putObject(cats, (long)Unsafe.ARRAY_OBJECT_BASE_OFFSET + (cats.length - 1) * Unsafe.ARRAY_OBJECT_INDEX_SCALE, new Cat("newcat", 10000)); // 获取最后一个元素的值 System.out.println("after put cats[2]=" + cats[2]); // 也可以这么获取,使用基础地址+偏移量的方式 System.out.println("after put cats[2]=" + unsafe.getObject(cats, (long)Unsafe.ARRAY_OBJECT_BASE_OFFSET + (cats.length - 1) * Unsafe.ARRAY_OBJECT_INDEX_SCALE)); System.out.println("-------------------"); }

输出:

Unsafe.ARRAY_BOOLEAN_BASE_OFFSET=16
Unsafe.ARRAY_BOOLEAN_INDEX_SCALE=1
Unsafe.ARRAY_BYTE_BASE_OFFSET=16
Unsafe.ARRAY_BYTE_INDEX_SCALE=1
Unsafe.ARRAY_SHORT_BASE_OFFSET=16
Unsafe.ARRAY_SHORT_INDEX_SCALE=2
Unsafe.ARRAY_CHAR_BASE_OFFSET=16
Unsafe.ARRAY_CHAR_INDEX_SCALE=2
Unsafe.ARRAY_INT_BASE_OFFSET=16
Unsafe.ARRAY_INT_INDEX_SCALE=4
Unsafe.ARRAY_LONG_BASE_OFFSET=16
Unsafe.ARRAY_LONG_INDEX_SCALE=8
Unsafe.ARRAY_FLOAT_BASE_OFFSET=16
Unsafe.ARRAY_FLOAT_INDEX_SCALE=4
Unsafe.ARRAY_DOUBLE_BASE_OFFSET=16
Unsafe.ARRAY_DOUBLE_INDEX_SCALE=8
Unsafe.ARRAY_OBJECT_BASE_OFFSET=16
Unsafe.ARRAY_OBJECT_INDEX_SCALE=4
------------------------------
before put array[2]=33
after put array[2]=100
after put array[2]=100
-------------------
static...
before put cats[2]=Cat{name='cat3', speed=3}
after put cats[2]=Cat{name='newcat', speed=10000}
after put cats[2]=Cat{name='newcat', speed=10000}
-------------------

Tips:

如果操作的元素位置没有在数组范围内的话,put和get操作不会异常,都会成功,因为这是内存操作,使用的是基础地址+偏移量,但是并没有改变原始数组的大小,put后可以获取相应位置的内存数据,在没有put前调用get则获取的是数据类型的默认值。

CAS

比较并交换(Compare And Swap),在jvm里是一个原子操作,先获取内存的值,然后判断内存值和预期值是否相同,相同则更新为新值表示操作成功,不同则直接返回false,表明操作失败。java里的JUC包下很多队列或者锁都采用了这种实现方式。

//每次都从主内存获取var1对象var2偏移量的long值
public native long getLong
首页 上一页 1 2 3 4 5 6 7 下一页 尾页 4/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇10、Spring之AOP概述 下一篇new ArrayList 不当导致 CPU 飙升..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目