Skip to content

Commit 6601e30

Browse files
committed
boolean 类型的大小
1 parent 31d5672 commit 6601e30

File tree

3 files changed

+98
-8
lines changed

3 files changed

+98
-8
lines changed

docs/basic-grammar/basic-data-type.md

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,11 @@ public class LocalVar {
6161
0
6262
```
6363

64-
瞧见没,int 作为成员变量时或者静态变量时的默认值是 0。那不同的基本数据类型,是有不同的默认值和大小的,来个表格感受下。
64+
瞧见没,int 作为成员变量时或者静态变量时的默认值是 0。那不同的基本数据类型,是有不同的默认值和占用大小的,来个表格感受下。
6565

6666
| 数据类型 | 默认值 | 大小 |
6767
| -------- | -------- | ------ |
68-
| boolean | false | 1 比特 |
68+
| boolean | false | 不确定 |
6969
| char | '\u0000' | 2 字节 |
7070
| byte | 0 | 1 字节 |
7171
| short | 0 | 2 字节 |
@@ -109,6 +109,92 @@ boolean hasMoney = true;
109109
boolean hasGirlFriend = false;
110110
```
111111

112+
根据 Java 语言规范,boolean 类型只有两个值 true 和 false,但在语言层面,Java 没有明确规定 boolean 类型的大小。
113+
114+
那经过我的调查,发现有两种论调。
115+
116+
我们先来看论调一。
117+
118+
对于单独使用的 boolean 类型,JVM 并没有提供专用的字节码指令,而是使用 int 相关的指令 istore 来处理,那么 int 明确是 4 个字节,所以此时的 boolean 也占用 4 个字节。
119+
120+
对于作为数组来使用的 boolean 类型,JVM 会按照 byte 的指令来处理(bastore),那么已知 byte 类型占用 1 个字节,所以此时的 boolean 也占用 1 个字节。
121+
122+
![二哥的 Java 进阶之路:javap 验证](https://cdn.tobebetterjavaer.com/stutymore/basic-data-type-20240602170355.png)
123+
124+
论调二,布尔具体占用的大小是不确定的,取决于 JVM 的具体实现。
125+
126+
>boolean: The boolean data type has only two possible values: true and false. Use this data type for simple flags that track true/false conditions. This data type represents one bit of information, but its "size" isn't something that's precisely defined.
127+
128+
可以通过 JOL 工具打印出对象的内存布局,展示 boolean 单独使用和作为数组使用时在内存中的实际占用大小。
129+
130+
```java
131+
public class BooleanSizeExample {
132+
public static void main(String[] args) {
133+
boolean singleBoolean = true;
134+
boolean[] booleanArray = new boolean[10];
135+
136+
// 分析内存占用,可以使用第三方工具如 JOL(Java Object Layout)
137+
System.out.println("Size of single boolean: " + org.openjdk.jol.info.ClassLayout.parseInstance(singleBoolean).toPrintable());
138+
System.out.println("Size of boolean array: " + org.openjdk.jol.info.ClassLayout.parseInstance(booleanArray).toPrintable());
139+
}
140+
}
141+
```
142+
143+
运行结果如下(64 操作系统 JDK 8):
144+
145+
```
146+
Size of single boolean: java.lang.Boolean object internals:
147+
OFFSET SIZE TYPE DESCRIPTION VALUE
148+
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
149+
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
150+
8 4 (object header) dd 20 00 f8 (11011101 00100000 00000000 11111000) (-134209315)
151+
12 1 boolean Boolean.value true
152+
13 3 (loss due to the next object alignment)
153+
Instance size: 16 bytes
154+
Space losses: 0 bytes internal + 3 bytes external = 3 bytes total
155+
156+
Size of boolean array: [Z object internals:
157+
OFFSET SIZE TYPE DESCRIPTION VALUE
158+
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
159+
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
160+
8 4 (object header) 05 00 00 f8 (00000101 00000000 00000000 11111000) (-134217723)
161+
12 4 (object header) 0a 00 00 00 (00001010 00000000 00000000 00000000) (10)
162+
16 10 boolean [Z.<elements> N/A
163+
26 6 (loss due to the next object alignment)
164+
Instance size: 32 bytes
165+
Space losses: 0 bytes internal + 6 bytes external = 6 bytes total
166+
```
167+
168+
对于单个 boolean 变量来说:
169+
170+
①、**对象头(Object Header)** 占用了 12 个字节:
171+
172+
- **OFFSET 0 - 4**:对象头的一部分,包含对象的标记字段(Mark Word),用于存储对象的哈希码、GC 状态等。
173+
- **OFFSET 4 - 8**:对象头的另一部分,通常是指向类元数据的指针(Class Pointer)。
174+
- **OFFSET 8 - 12**:对象头的最后一部分,包含锁状态或其他信息。
175+
176+
②、实际的 `boolean` 值占用 1 个字节,也就是**OFFSET 12 - 13**
177+
178+
③、为了满足 8 字节的对齐要求(HotSpot JVM 默认的对象对齐方式),有 3 个字节的填充。**OFFSET 13 - 16**
179+
180+
也就是说,尽管 `boolean` 值本身只需要 1 个字节,但由于对象头和对齐要求,一个 `boolean` 在内存中占用 16 字节。
181+
182+
对于 `boolean` 数组来说:
183+
184+
①、**对象头(Object Header)** 占用了 12 个字节:
185+
186+
- **OFFSET 0 - 4**:对象头的一部分,包含对象的标记字段(Mark Word)。
187+
- **OFFSET 4 - 8**:对象头的另一部分,包含指向类元数据的指针(Class Pointer)。
188+
- **OFFSET 8 - 12**:对象头的最后一部分,通常包含数组的长度信息。
189+
190+
②、**数组长度** 占用了 4 个字节,此处是 10,**OFFSET 12 - 16**
191+
192+
③、实际的 `boolean` 数组元素,每个 `boolean` 值占用 1 个字节,总共 10 个字节,**OFFSET 16 - 26**
193+
194+
④、为了满足 8 字节对齐要求,有 6 个字节的填充,**OFFSET 26 - 32**
195+
196+
也就是说,每个 `boolean` 数组元素占用 1 个字节,加上对象头、对齐填充和数组长度,包含 10 个元素的 `boolean` 数组占用 32 字节。
197+
112198
#### 2)byte
113199

114200
一个字节可以表示 2^8 = 256 个不同的值。由于 byte 是有符号的,它的值可以是负数或正数,其取值范围是 -128 到 127(包括 -128 和 127)。

docs/sidebar/sanfene/javase.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,11 @@ Java 的数据类型分两种:**基本数据类型**和**引用数据类型**
147147
- 字符型(char)
148148
- 布尔型(boolean)
149149

150-
Java 基本数据类型范围和默认值
150+
Java 基本数据类型的默认值和占用大小
151151

152152
| 数据类型 | 默认值 | 大小 |
153153
| -------- | -------- | ------ |
154-
| boolean | false | 4字节 |
154+
| boolean | false | 不确定 |
155155
| char | '\u0000' | 2 字节 |
156156
| byte | 0 | 1 字节 |
157157
| short | 0 | 2 字节 |
@@ -166,11 +166,15 @@ Java 基本数据类型范围和默认值:
166166
- [接口](https://javabetter.cn/oo/interface.html)(interface)
167167
- [数组](https://javabetter.cn/array/array.html)`[]`
168168

169-
#### 为什么 boolean 占四个字节
169+
#### boolean 类型实际占用几个字节
170170

171-
如果 boolean 是 单独使用的,它会被编译为 int 类型,占用 4 个字节。
171+
推荐阅读:[二哥的 Java 进阶之路:基本数据类型篇](https://javabetter.cn/basic-grammar/basic-data-type.html)
172172

173-
如果 boolean 是作为数组的元素,它会被编译为 byte 类型,占用 1 个字节。
173+
这要依据具体的 JVM 实现细节,但是在 Java 虚拟机规范中,并没有明确规定 boolean 类型的大小,只是规定 boolean 类型只能取 true 或 false 两个值。
174+
175+
>boolean: The boolean data type has only two possible values: true and false. Use this data type for simple flags that track true/false conditions. This data type represents one bit of information, but its "size" isn't something that's precisely defined.
176+
177+
我本机的 64 位 JDK 中,通过 JOL 工具查看单独的 boolean 类型,以及 boolean 数组,所占用的空间都是 1 个字节。
174178

175179
> 1. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的用友金融一面原题:Java 有哪些基本数据类型?
176180
> 2. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的快手面经同学 1 部门主站技术部面试原题:Java 的基础数据类型,分别占多少字节

docs/string/string-source.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: 深入解读String类源码及其应用技巧
2+
title: 深入解读String类的源码
33
shortTitle: 字符串源码解读
44
category:
55
- Java核心

0 commit comments

Comments
 (0)