【JVM】javap命令行分析揭示boolean的本质的虚拟机指令
源代码
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位。
结论
- boolean类型实际不存在,在JVM中使用0/1表示false/true。
- boolean类型占用字节数没有被规定,这与编译器、虚拟机等有关。
- 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的本质的虚拟机指令相关推荐
- 【JVM】javap命令行分析(a++ + ++a)的虚拟机指令
源代码 public class PlusTest {public static void main(String[] args) {int a = 2;System.out.println(a++ ...
- JVM常见命令行及图形工具
目录 JDK 命令行工具 jps:查看所有 Java 进程 jinfo:实时地查看和调整虚拟机各项参数 jstat:监视虚拟机各种运行状态信息 jmap:生成堆转储快照 jhat:分析 heapdum ...
- JVM监控-命令行篇
1. 概述 性能诊断是软件工程师在日常工作中需要经常面对和解决的问题,在用户体验至上的今天,解决好应用的性能问题能带来非常大的收益. Java作为最流行的编程语言之一,其应用性能诊断一直受到业界广泛关 ...
- GCC笔记 命令行分析
1984年,Richard Stallman发起了自由软件运动,GNU (Gnu's Not Unix)项目应运而生,3年后,最初版的GCC横空出世,成为第一款可移植.可优化.支持ANSI C的开源C ...
- 【转】Linux 命令行下的好东西:一些常用指令
Table of Contents tmux tree ack rsync aspell tee +r> cloc printenv find type help env file string ...
- 命令行分析java线程CPU占用
1.使用top命令找出占用cpu最高的JAVA进程pid号 2. 找出占用cpu最高的线程: top -Hp pid -d 1 -n 1 3. 打印占CPU最高JAVA进程pid的堆栈信息 jsta ...
- GC调优基础知识之工具篇--jdk为我们提供的命令行命令 jps,jstat,jmap,jinfo,jstat,jstack,jhat 等
一. JDK为我们提供的工具: 在Windows中对于这些命令的支持是源自JDK -->bin下面的.exe可执行文件的支持. 在Linux中对于这些命令的支持是源自JDK --&g ...
- 从docker 中抓取jvm heap 信息, 并且分析
1, 查看JVM进程 # jps ----------------------------- 11921 WrapperSimpleApp 4082 Jps 9768 QuorumPeerMain 1 ...
- JVM从入门到精通(七):GC常用参数,Method Area,JVM调优案例分析
GC常用参数 -Xmn -Xms -Xmx -Xss 年轻代 最小堆 最大堆 栈空间 -XX:+UseTLAB 使用TLAB,默认打开 -XX:+PrintTLAB 打印TLAB的使用情况 -XX:T ...
最新文章
- windows串口控制linux,linux及windows下串口的使用.doc
- 如何理解物体的6D位姿估计任务?
- 趣味理解:三层架构与养猪—《.NET深入体验与实战精要》
- java知识理论_JAVA理论知识 - OSC_rnoszD的个人空间 - OSCHINA - 中文开源技术交流社区...
- 网络营销——网络营销专员浅析网站推广营销关键词是重点
- laravel判断HTTP请求是否ajax
- STM32之独立版USB(Host)驱动+MSC+Fatfs移植
- spring boot自定义配置文件
- 基于sklearn的朴素贝叶斯_Sklearn参数详解—贝叶斯
- java中的equals方法+hashCode方法
- MacBook如何快速显示桌面
- FirstDjangoWebApp-1
- 485串口测试工具软件_(案例)电脑和仪表之间485通讯的奇怪现象及解决方案
- Understanding Linux CPU Load - when should you be worried?
- 计算机基础(四):C语言字符串处理文件保存
- Unix 网络编程 I/O 模型 第六章
- Python 编写几个经典例子
- 开源面向对象数据库 db4o 之旅,第 1 部分: 初识 db4o
- 【学习笔记】通过雷达获取某一角度的距离信息
- Java程序语言(基础篇)第2章 基本程序设计 编程练习题解答