源代码

public class BooleanTest {public static void main(String[] args) {boolean a = true;boolean b = false;System.out.println(a);System.out.println(b);}
}

编译

>javac BooleanTest.java

执行

>java BooleanTest
true
false

反汇编

>javap -c BooleanTest
Compiled from "BooleanTest.java"
public class BooleanTest {public BooleanTest();Code:0: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: returnpublic static void main(java.lang.String[]);Code:0: iconst_11: istore_12: iconst_03: istore_24: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;7: iload_18: invokevirtual #3                  // Method java/io/PrintStream.println:(Z)V11: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;14: iload_215: invokevirtual #3                  // Method java/io/PrintStream.println:(Z)V18: return
}

main()的虚拟机指令分析

iconst_1

上面的指令表示先生成一个常量,值为1,实际上是true。

istore_1

上面的指令表示将常量1赋值给第一个变量(在jshell里就是$1)

iconst_0

上面的指令表示先生成一个常量,值为0,实际上是false。

istore_2

上面的指令表示将常量0赋值给第二个变量(在jshell里就是$2)

getstatic

由于System.out.println()其中的System.out其实是java.lang.System中的一个静态的属性,所以这个指令顾名思义,就是获取这样一个静态属性。
这个System.out的类型其实是java.io.PrintStream,这点我们在之前的文章中也说过了,感兴趣的可以查看源码自行了解。

iload_1

将$1压栈,加到虚拟机栈空间中。

invokevirtual

调用System.out的println(),打印$1的值,输出true。

getstatic

再次获取System.out

iload_2

将$2压栈,加到虚拟机栈空间中。

invokevirtual

调用System.out的println(),打印$2的值,输出false。

return

main()返回值为void,使用return结束方法,相当于C/C++中int main()最后的return 0。

深入探讨boolean字节数

引自——http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html的说明:

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.

【翻译】
布尔值:布尔数据类型只有两个可能的值:true和false。 将此数据类型用于跟踪真/假条件的简单标志。 此数据类型代表一小部分信息,但其“大小”并不是精确定义的。

其实学过C语言的大家也知道,C中没有boolean/bool这种类型的变量,只需要使用0/1即可,经过测试我们也知道,哪有boolean这种东西啊?计算机中所有的运算都是0/1序列,怎么存在真正的boolean?

同样的,既然本身不存在,那其占用空间与实现方式有关,而实现方式由编译器、虚拟机等决定。

《Java虚拟机规范》书中说到:
虽然定义了boolean这种数据类型,但是只对它提供了非常有限的支持。在Java虚拟机中没有任何供boolean值专用的字节码指令,Java语言表达式所操作的boolean值,在编译之后都使用Java虚拟机中的int数据类型来代替,而boolean数组将会被编码成Java虚拟机的byte数组,每个元素boolean元素占8位。

结论

  1. boolean类型实际不存在,在JVM中使用0/1表示false/true。
  2. boolean类型占用字节数没有被规定,这与编译器、虚拟机等有关。
  3. boolean类型在规范标准的虚拟机中占4个字节;但规定boolean数组中每一个boolean使用1个字节的byte表示以节约空间。(所以说,网传1字节特别是1bit的,基本认定是骗人的)

再思考:4字节/1字节?

Java有四种整数类型,byte(1 bit)、short(2 bits)、int(4 bits)、long(8 bits)。

已知boolean就是使用0/1整数表示的前提下,使用byte表示boolean可以节约空间,这对于长数组或者大规模多维数组来说还是挺重要的。

而使用int表示普通boolean,看似消耗了更多的空间,但实际上考虑到在32位/64位的机器上进行运算,int显然更方便一些,对计算本身很友好。

这种选择正是体现了计算机科学中的“Trade Off”,我在很多文章里都提到过,很orz这个词。我们还是要在不完美中选择最适合具体情况的最优解啊orz。

【JVM】javap命令行分析揭示boolean的本质的虚拟机指令相关推荐

  1. 【JVM】javap命令行分析(a++ + ++a)的虚拟机指令

    源代码 public class PlusTest {public static void main(String[] args) {int a = 2;System.out.println(a++ ...

  2. JVM常见命令行及图形工具

    目录 JDK 命令行工具 jps:查看所有 Java 进程 jinfo:实时地查看和调整虚拟机各项参数 jstat:监视虚拟机各种运行状态信息 jmap:生成堆转储快照 jhat:分析 heapdum ...

  3. JVM监控-命令行篇

    1. 概述 性能诊断是软件工程师在日常工作中需要经常面对和解决的问题,在用户体验至上的今天,解决好应用的性能问题能带来非常大的收益. Java作为最流行的编程语言之一,其应用性能诊断一直受到业界广泛关 ...

  4. GCC笔记 命令行分析

    1984年,Richard Stallman发起了自由软件运动,GNU (Gnu's Not Unix)项目应运而生,3年后,最初版的GCC横空出世,成为第一款可移植.可优化.支持ANSI C的开源C ...

  5. 【转】Linux 命令行下的好东西:一些常用指令

    Table of Contents tmux tree ack rsync aspell tee +r> cloc printenv find type help env file string ...

  6. 命令行分析java线程CPU占用

    1.使用top命令找出占用cpu最高的JAVA进程pid号 2. 找出占用cpu最高的线程: top -Hp pid  -d 1 -n 1 3. 打印占CPU最高JAVA进程pid的堆栈信息 jsta ...

  7. GC调优基础知识之工具篇--jdk为我们提供的命令行命令 jps,jstat,jmap,jinfo,jstat,jstack,jhat 等

    一. JDK为我们提供的工具:    在Windows中对于这些命令的支持是源自JDK -->bin下面的.exe可执行文件的支持.    在Linux中对于这些命令的支持是源自JDK --&g ...

  8. 从docker 中抓取jvm heap 信息, 并且分析

    1, 查看JVM进程 # jps ----------------------------- 11921 WrapperSimpleApp 4082 Jps 9768 QuorumPeerMain 1 ...

  9. JVM从入门到精通(七):GC常用参数,Method Area,JVM调优案例分析

    GC常用参数 -Xmn -Xms -Xmx -Xss 年轻代 最小堆 最大堆 栈空间 -XX:+UseTLAB 使用TLAB,默认打开 -XX:+PrintTLAB 打印TLAB的使用情况 -XX:T ...

最新文章

  1. windows串口控制linux,linux及windows下串口的使用.doc
  2. 如何理解物体的6D位姿估计任务?
  3. 趣味理解:三层架构与养猪—《.NET深入体验与实战精要》
  4. java知识理论_JAVA理论知识 - OSC_rnoszD的个人空间 - OSCHINA - 中文开源技术交流社区...
  5. 网络营销——网络营销专员浅析网站推广营销关键词是重点
  6. laravel判断HTTP请求是否ajax
  7. STM32之独立版USB(Host)驱动+MSC+Fatfs移植
  8. spring boot自定义配置文件
  9. 基于sklearn的朴素贝叶斯_Sklearn参数详解—贝叶斯
  10. java中的equals方法+hashCode方法
  11. MacBook如何快速显示桌面
  12. FirstDjangoWebApp-1
  13. 485串口测试工具软件_(案例)电脑和仪表之间485通讯的奇怪现象及解决方案
  14. Understanding Linux CPU Load - when should you be worried?
  15. 计算机基础(四):C语言字符串处理文件保存
  16. Unix 网络编程 I/O 模型 第六章
  17. Python 编写几个经典例子
  18. 开源面向对象数据库 db4o 之旅,第 1 部分: 初识 db4o
  19. 【学习笔记】通过雷达获取某一角度的距离信息
  20. Java程序语言(基础篇)第2章 基本程序设计 编程练习题解答

热门文章

  1. WebSocket使用中Stomp Client连接报ERROR CODE 200的解决办法
  2. Luogu P1280 Niko的任务【线性dp】By cellur925
  3. openssl解析国密X509证书
  4. spring3: 切面及通知实例 Aspectj的aop
  5. java基础基础总结----- Date
  6. soapUI-JDBC Request
  7. iOS基础 - 控制器
  8. [读书笔记] Effective C++
  9. Hadoop集群的kerberos认证
  10. php checkbox 保存,PHP中在数据库中保存Checkbox数据