字节序:指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序,有大端和小端两种方式,在不同的应用场景下这两种存储各有优势。
大端:指高位字节存放在内存的低地址端,低位字节存放在内存的高地址端。十六进制整数0x01020304在内存中存储方式,由于一个整型在内存中占4个字节,因此被划分成4份分别存储在连续的内存地址位中
| 内存地址 | 0x004060 | 0x004061 | 0x004062 | 0x004063 |
|---|---|---|---|---|
| 数据值 | 01 | 02 | 03 | 04 |
小端:指低位字节放在内存的低地址端,高位字节放在内存的高地址端。同样0x01020304在内存中的存储方式为
| 内存地址 | 0x004060 | 0x004061 | 0x004062 | 0x004063 |
|---|---|---|---|---|
| 数据值 | 04 | 03 | 02 | 01 |
jvm对基本数字类型的存储
在java基本类型中,诸如赋值语句byte a = (byte)1;从使用上不难看出这是小端存储的方式,才能安全的向下转型。
同时我们可以用UnSafe类直接操作内存进行验证。
private static Unsafe getUnsafe() {try {Field field = Unsafe.class.getDeclaredField("theUnsafe");field.setAccessible(true);return (Unsafe) field.get(null);} catch (Exception e) {return null;}}public static void main(String[] args) {final Unsafe unsafe = getUnsafe();final long addr = unsafe.allocateMemory(2);unsafe.putShort(addr, (short) 1);final byte lowerNum = unsafe.getByte(addr);//获取一个字节System.out.println(lowerNum);// 存放一个超过一个字节大小的数 如256->第二个字节第一位为1unsafe.putShort(addr, (short) 256);final byte higherNum = unsafe.getByte(addr + 1);// 获取第二个字节数据System.out.println(higherNum);}
输出:
1 1
jvm对对象头的存储
先上示例
添加依赖
<dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-core</artifactId><version>0.9</version></dependency>
实例对象
public class Worker {private Integer id;private String username;private String password;private short age;}
测试代码
public static void main(String[] args) {Worker work = new Worker();// hashCodeSystem.out.println("hashCode: " + work.hashCode() + " 十六进制表示:0X" + HexUtil.toHex(work.hashCode()));// 对象内存布局System.out.println(ClassLayout.parseInstance(work).toPrintable());}
输出:
hashCode: 1735600054 十六进制表示:0X677327b6com.obj.header.Worker object internals:OFFSET SIZE TYPE DESCRIPTION VALUE0 4 (object header) 01 b6 27 73 (00000001 10110110 00100111 01110011) (1931982337)4 4 (object header) 67 00 00 00 (01100111 00000000 00000000 00000000) (103)8 4 (object header) 43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)12 2 short Worker.age 014 2 (alignment/padding gap)16 4 java.lang.Integer Worker.id null20 4 java.lang.String Worker.username null24 4 java.lang.String Worker.password null28 4 (loss due to the next object alignment)Instance size: 32 bytesSpace losses: 2 bytes internal + 4 bytes external = 6 bytes total
对比可见实例对象的hashcode是大端存储。
