CS-Wiki CS-Wiki
Home
知识体系总览
  • 数据结构与算法
  • 计算机网络
  • 操作系统
  • MySQL
  • Redis
  • 设计模式
  • Java 基础
  • Java 集合
  • Java 并发
  • Java 虚拟机
  • Spring
  • Kafka
  • 校招扫盲
  • 项目推荐
  • 唠唠嗑儿
  • 读书笔记
归档
GitHub (opens new window)
Home
知识体系总览
  • 数据结构与算法
  • 计算机网络
  • 操作系统
  • MySQL
  • Redis
  • 设计模式
  • Java 基础
  • Java 集合
  • Java 并发
  • Java 虚拟机
  • Spring
  • Kafka
  • 校招扫盲
  • 项目推荐
  • 唠唠嗑儿
  • 读书笔记
归档
GitHub (opens new window)
  • Java基础

    • 基础

      • 万物皆对象
      • HelloWorld
      • 运算符与控制流
      • 深入理解Java数组
      • 面试官竟然问我这么简单的题目:Java 中 boolean 占多少字节?我脱出而出
    • 对象与类

    • 抽象类与接口

    • 异常

    • 反射和动态代理

    • IO

    • 注解

  • Java集合

  • Java并发

  • Java虚拟机

  • Java 新版本特性

  • 30-Java
  • Java基础
  • 基础
小牛肉
2022-07-06

面试官竟然问我这么简单的题目:Java 中 boolean 占多少字节?我脱出而出

  • 面试官:Java 中 boolean 占多少字节?
  • 我:1 个字节
  • 面试官:emm 你确定吗
  • 我:(开始慌了)确....定.....吧
  • 面试官:好的,那你这边还有什么问题吗?
  • 我:卒......

这种概念性问题,最权威最准确的就是查官网文档

Oracle 官方文档地址在此:https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

总共 8 大基础数据类型,其余 7 个都非常明确的标明了占用多少字节,只有 boolean 模棱两可:

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.

翻译下划线部分:这个数据类型表示 1 bit 的信息(true or false,编译后用 0 或 1 来表示),但是它的 size 并没有被精确地定义。也就是说,不管它占多大的空间,只有 1 个 bit 的信息是有意义的。

事实上,boolean 到底占用多少大小的空间,“It's virtual machine dependent.”,完全取决于 Java 虚拟机本身的设计。

不过显然 boolean 是肯定不可能只占用 1 个 bit 的,最起码也是 1 个 Bytes(字节),因为计算机处理数据的最小单位是 1 个字节

《Java 虚拟机规范》对于 boolean 到底占用多少空间提供了一定的建议(只是建议,具体的实现仍然取决于每个虚拟机是否按照规范来),官方文档在这里:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.3.4

Although the Java Virtual Machine defines a boolean type, it only provides very limited support for it. There are no Java Virtual Machine instructions solely dedicated to operations on boolean values. Instead, expressions in the Java programming language that operate on boolean values are compiled to use values of the Java Virtual Machine int data type.

尽管 Java 虚拟机定义了一个布尔类型,但是它只提供了非常有限的支持,并【没有】专门用于对【boolean 值】进行操作的 Java 虚拟机指令。相反,Java 中操作 boolean 值的表达式被编译为使用 int 数据类型的值。

The Java Virtual Machine does directly support boolean arrays. Its newarray instruction (newarray) enables creation of boolean arrays. Arrays of type boolean are accessed and modified using the byte array instructions baload and bastore.

不过,Java 虚拟机【直接支持】【boolean 数组】,通过 newarray 指令创建 boolean 数组,然后通过 byte 数组指令 baload 和 bastore 来访问和修改 boolean 数组。

  • newarray 指令:Create new array
  • baload 指令:Load byte or boolean from array
  • bastore 指令:Store into byte or boolean array

In Oracle’s Java Virtual Machine implementation, boolean arrays in the Java programming language are encoded as Java Virtual Machine byte arrays, using 8 bits per boolean element.

在 Oracle 的 Java 虚拟机实现中,Java 中的 boolean 数组被编码为 byte 数组,每个 boolean 元素使用 1 字节(8 bit)。


总结下,Java 虚拟机规范提议:

  • 如果 boolean 是 “单独使用”:boolean 被编译为 int 类型,占 4 个字节
  • 如果boolean 是以 “boolean 数组” 的形式使用:boolean 占 1 个字节,Java 虚拟机直接支持 boolean 数组,通过 newarray 指令创建 boolean 数组,然后通过 byte 数组指令 baload 和 bastore 来访问和修改 boolean 数组

具体还要看虚拟机实现是否按照规范来,所以 boolean 占用 1 个字节、4 个字节都是有可能的

可以通过下述代码来检测下:

class LotsOfBooleans {
    boolean a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af;
    boolean b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf;
    boolean c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf;
    boolean d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df;
    boolean e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ea, eb, ec, ed, ee, ef;
}

class LotsOfInts {
    int a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af;
    int b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf;
    int c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf;
    int d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df;
    int e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ea, eb, ec, ed, ee, ef;
}


public class Test {
    private static final int SIZE = 1000000;

    public static void main(String[] args) throws Exception {        
        LotsOfBooleans[] first = new LotsOfBooleans[SIZE];
        LotsOfInts[] second = new LotsOfInts[SIZE];

        System.gc();
        long startMem = getMemory();

        for (int i=0; i < SIZE; i++)
        {
            first[i] = new LotsOfBooleans();
        }

        System.gc();
        long endMem = getMemory();

        System.out.println ("Size for LotsOfBooleans: " + (endMem-startMem));
        System.out.println ("Average size: " + ((endMem-startMem) / ((double)SIZE)));

        System.gc();
        startMem = getMemory();
        for (int i=0; i < SIZE; i++)
        {
            second[i] = new LotsOfInts();
        }
        System.gc();
        endMem = getMemory();

        System.out.println ("Size for LotsOfInts: " + (endMem-startMem));
        System.out.println ("Average size: " + ((endMem-startMem) / ((double)SIZE)));

        // Make sure nothing gets collected
        long total = 0;
        for (int i=0; i < SIZE; i++)
        {
            total += (first[i].a0 ? 1 : 0) + second[i].a0;
        }
        System.out.println(total);
    }

    private static long getMemory() {
        Runtime runtime = Runtime.getRuntime();
        return runtime.totalMemory() - runtime.freeMemory();
    }
}

再强调一遍,boolean 占用多少字节取决于虚拟机本身的实现,在 Windows 上 Sun's JDK build 1.6.0_11 的结果如下,这意味着 boolean 值(单独使用)的时候占用 1 个字节:

Size for LotsOfBooleans: 87978576
Average size: 87.978576
Size for LotsOfInts: 328000000
Average size: 328.0

🎁 公众号

各位小伙伴大家好呀,叫我小牛肉就行,目前在读东南大学硕士,上方扫码关注公众号「飞天小牛肉」,与你分享我的成长历程与技术感悟~

帮助小牛肉改善此页面 (opens new window)
Last Updated: 2023/02/16, 11:27:10
深入理解Java数组
对象初始化和清理

← 深入理解Java数组 对象初始化和清理→

最近更新
01
02
线上环境 CPU 使用率飙升如何快速排查?
03-05
03
面试官再跟你说中国没有根服务器,雪人计划让他了解下
02-23
更多文章>
Theme by Vdoing | Copyright © 2019-2023 飞天小牛肉 | 皖ICP备2022008966号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式