网站首页 > 文章精选 正文
内存中存放数据有两种模式:大端存储(大端模式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;
/**
* 博客地址:www.myydream.com
* 公众号:毛毛的梦想
*/
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;
/**
* 博客地址:www.myydream.com
* 公众号:毛毛的梦想
*/
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()=2061475679
com.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 5
Instance size: 16 bytes
Space 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 00000000
31位hashcode:01011111 10011111 11011111 01111010 (最后一位补0)
1位预留位:0
4位GC分代年龄:0000
1位偏向锁位:0
2位锁标志位: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 0Xf
0X0相对于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使用的是大端存储。即:高字节存储在低地址,低字节存储在高地址。
猜你喜欢
- 2025-07-21 [西门子PLC] 两个S7-1200之间实现Modbus TCP客户端和服务器通信
- 2025-07-21 谈谈西门子PLC中的字位变换(西门子plc的字和位)
- 2025-07-21 史上最全齿轮类型介绍及主要参数计算与画法详解
- 2025-07-21 机械设计中的尺寸标注(机械设计中的尺寸标注,看懂复杂机械图纸)
- 2025-07-21 FANUC 0iTF 车床编程 G90 车削锥度指令
- 2025-07-21 C语言验证大小端的几个方法(用c语言实现大小端的测试)
- 2025-07-21 机器人也要“减重”? 机械臂用上碳纤维复合材料,性能或大有提升
- 2025-07-21 揭秘通信协议设计的奥妙,作为面试官我都看蒙了
- 2025-07-21 新手攻略!入门ARM必须要理解的22个常用概念
- 2025-07-21 NPT 螺纹与英制螺纹的区别大揭秘(英制螺纹和npt)
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)
- mysql数据库面试题 (57)
- fmt.println (52)