龙空技术网

大端存储和小端存储

myydream 140

前言:

现时咱们对“小端java”大体比较珍视,大家都需要学习一些“小端java”的相关资讯。那么小编也在网络上网罗了一些有关“小端java””的相关知识,希望各位老铁们能喜欢,大家一起来学习一下吧!

内存中存放数据有两种模式:大端存储(大端模式Bog-Endian)和小端存储(小端模式Little-Endian)。

为什么会说这个呢?是因为在学习对象头object header时需要这个知识点。

测试环境:

Darwin bogon 21.1.0 Darwin Kernel Version 21.1.0: Wed Oct 13 17:33:23 PDT 2021; root:xnu-8019.41.5~1/RELEASE_X86_64 x86_64

有如下程序:

package com.myydream.demo;/** * 博客地址: * 公众号:毛毛的梦想 */public class Monkey {    private int age;    public Monkey(int age) {        this.age = age;    }    public void printAge() {        System.out.println(this.age);    }}

引入依赖:

<dependency>     <groupId>org.openjdk.jol</groupId>     <artifactId>jol-core</artifactId>     <version>0.9</version></dependency>

编写测试程序:

package com.myydream.demo;import org.openjdk.jol.info.ClassLayout;/** * 博客地址: * 公众号:毛毛的梦想 */public class Test {    public static void main(String[] args) {        Monkey monkey = new Monkey(5);        //只有真正使用过hashcode,对象头中才会添加hashcode,否则都是默认值0。这个读者自己验证即可        System.out.println("monkey.hashCode()=" + monkey.hashCode());        System.out.println(ClassLayout.parseInstance(monkey).toPrintable());    }}

运行结果:

monkey.hashCode()=2061475679com.myydream.demo.Monkey object internals: OFFSET  SIZE   TYPE DESCRIPTION        VALUE      0     4        (object header)    01 5f 9f df (00000001 01011111 10011111 11011111) (-543203583)      4     4        (object header)    7a 00 00 00 (01111010 00000000 00000000 00000000) (122)      8     4        (object header)    49 1a 17 00 (01001001 00011010 00010111 00000000) (1514057)     12     4    int Monkey.age         5Instance size: 16 bytesSpace losses: 0 bytes internal + 0 bytes external = 0 bytes total

我们这是一个普通的对象,因此对象头中的Mark Word存储数据为:

unused:25 hash:31 -->| unused:1   age:4    biased_lock:1 lock:2 (normal object)

翻译一下:25(未使用,即预留位) + 31(hash code) + 1(未使用,即预留位) + 4(GC分代年龄) + 1(偏向锁位) + 2(锁标志位) = 64

前64个bit为:

OFFSET  SIZE   TYPE DESCRIPTION        VALUE  0     4        (object header)    01 5f 9f df (00000001 01011111 10011111 11011111) (-543203583)  4     4        (object header)    7a 00 00 00 (01111010 00000000 00000000 00000000) (122)

按照上面说的前25位为预留位,那么这64位应该是从后往前,即:

25位预留位:0 00000000 00000000 0000000031位hashcode:01011111 10011111 11011111 01111010 (最后一位补0)1位预留位:04位GC分代年龄:00001位偏向锁位:02位锁标志位:01

从输出能看到,monkey对象的hashcode为:2061475679,转化为二进制为:

1111010110111111001111101011111, 和 31位hashcode:01011111 10011111 11011111 01111010 根本不相等。

这里就需要用到文章开头说的大端存储还是小端存储了。

大端存储:数据的高字节存储在低地址中,数据的低字节存储在高地址中

怎么理解这句话呢。看看下面这个例子:

以java语言为例,int型数据占用4个字节。如int型x=5,二进制表现形式为:00000000 00000000 00000000 00001111以16进制表示为:0X0 0X0 0X0 0Xf再来看上面那句话:数据的高字节存储在低地址中,数据的低字节存储在高地址中。则大端存储int x = 5; 在内存中的分布为:0Xf 0X0 0X0 0X0  (0X0相对于0Xf属于数据的高字节,高字节存储在低地址中)

小端存储:数据的高字节存储在高地址中,数据的低字节存储在低地址中

还是看上面的例子:

以java语言为例,int型数据占用4个字节。如int型x=5,二进制表现形式为:00000000 00000000 00000000 00001111以16进制表示为:0X0 0X0 0X0 0Xf0X0相对于0Xf属于高字节。高字节存储在高地址中,则x在内存中的分布为:0X0 0X0 0X0 0Xf

接下来我们首先假设jvm使用的是大端存储:

01011111 10011111 11011111 01111010 转成16进制为:0X5f 0X9f 0Xdf 0X7a

如果是大端存储,正确的顺序应该是:0X7a 0Xdf 0X9f 0X5f ,转换成十进制为:2061475679等于输出的数据。

再假设jvm使用的是小端存储,则正确的顺序为0X5f 0X9f 0Xdf 0X7a,转成十进制为:1604312954,不等于输出数据。

因此我们可以知道jvm使用的是大端存储。即:高字节存储在低地址,低字节存储在高地址。

标签: #小端java