- @return
*/
public static Long getAddress(Object obj) {
Object[] objects = new Object[] {obj};
Unsafe unsafe = UnsafeFactory.getUnsafe();
int arrayBaseOffset = unsafe.arrayBaseOffset(Object[].class);
return unsafe.getLong(objects, arrayBaseOffset);
}
/**
-
获取对象的大小
-
@Dscription
-
Java中实例化一个对象时,JVM会在堆中分配非static的Field的内存,其他的static属性或者method在类加载期间或者JVM启动时已经存放在内存中。
-
所以我们计算对象的大小的时候只需要求和Field的大小就行了,JVM分配内存时,单个实例对象中的Field内存是连续不断地,
-
因此我们只需获取最大偏移量Filed的偏移量 + 最大偏移量Filed本身的大小即可
-
Java中基本数据类型所占的字节数
-
byte/boolean 1 字节
-
char/short 2 字节
-
int/float 4 字节
-
long/double 8 字节
-
boolean 理论上占1/8字节,实际上按照1byte处理。
-
Java采用的是Unicode编码,每一个字节占8位,一个字节由8个二进制位组成。
-
@param clazz
-
@return
*/
public static Long size(Class clazz) {
// 最后一个Filed的内存偏移量
long maxOffset = 0;
Class lastFiledClass = null;
Unsafe unsafe = UnsafeFactory.getUnsafe();
do {
for (Field field : clazz.getDeclaredFields()) {
if (!Modifier.isStatic(field.getModifiers())) {
long tmpOffset = unsafe.objectFieldOffset(field);
if (tmpOffset > maxOffset) {
maxOffset = tmpOffset;
lastFiledClass = field.getType();
}
}
}
} while ((clazz = clazz.getSuperclass()) != null);
// 最后一个Field本身的大小
int lastFiledSize = (boolean.class.equals(lastFiledClass) || byte.class.equals(lastFiledClass)) ? 1 :
(short.class.equals(lastFiledClass) || char.class.equals(lastFiledClass)) ? 2 :
(int.class.equals(lastFiledClass) || float.class.equals(lastFiledClass)) ? 4 : 8 ;
return maxOffset + lastFiledSize;
}
/**
-
申请一块固定大小的内存空间
-
@Description
-
通过Unsafe的public native long allocateMemory(long var1);申请一块内存空间。
-
@param bytes 需要申请的内存大小
-
@return
*/
public static Long allocateMemory(long bytes) {
return UnsafeFactory.getUnsafe().allocateMemory(bytes);
}
/**
-
从原对象内存地址srcAddr复制大小位size的内存到destAddr地址处
-
@param srcAddr 源地址
-
@param destAddr 目标地址
-
@param size 复制内存大小
*/
public static void copyMemory(long srcAddr, long destAddr, long size) {
UnsafeFactory.getUnsafe().copyMemory(srcAddr, destAddr, size);
}
/**
-
Unsafe未提供直接读取内存转为Java对象的方法,但是可以通过新建一个包含T类型属性的对象将申请的内存地址赋值给T属性
-
@param addr
-
@param
-
@return
*/
public static T addressConvertObject(long addr) {
Object[] objects = new Object[] {null};
Unsafe unsafe = UnsafeFactory.getUnsafe();
int baseOffset = unsafe.arrayBaseOffset(Object.class);
unsafe.putLong(objects, baseOffset, addr);
return (T)objects[0];
}
/**
-
实现对象的浅克隆
-
@Description
-
数组的无法通过此方法实现克隆,数组类是在JVM运行时动态生成的
-
@param t
-
@param
-
@return
*/
public static T shallowClone(T t) {
Class<?> clazz = t.getClass();
if (clazz.isArray()) {
Object[] objects = (Object[]) t;
return (T) Arrays.copyOf(objects, objects.length);
}
Long srcAddr = getAddress(t);
Long size = size(clazz);
Long destAddr = allocateMemory(size);
copyMemory(srcAddr, destAddr, size);
最后
由于篇幅原因,就不多做展示了
92)]
[外链图片转存中…(img-1XzJFo0P-1714479794393)]
[外链图片转存中…(img-YobXQyAb-1714479794393)]
[外链图片转存中…(img-kexVICE6-1714479794393)]
[外链图片转存中…(img-fFhUb2Ln-1714479794394)]
[外链图片转存中…(img-ieVoMhiZ-1714479794394)]
由于篇幅原因,就不多做展示了