字节码

Java所有的指令有200个作用,一个字节(8位) 可以存储256种不同的指令信息,一个这样的字节称为字节码(Bytecode).
在代码的执行过程中,JVM 量字节码解释执行,屏蔽对底层操作系统的依赖; JVM 也可以将字节码编译执行,如果是热点代码,会通过JIT 动态地编译为机器码,提高执行效率.
走进JVM--字节码
如图所示:十六进制表示的二进制流通常是一个操作指令.起始的4个字节非常特殊,即绿色框的 cafe babe (十六进制) 是 Gosling 定义的一个魔法数,意思是Coffee Baby, 它的作用是: 标志该文件是一个Java类文件,如果没有识别到该标志,说明该文件不是Java类文件或文件已受损,无法进行加载. 而红色框表示当前版本号,0x37 的十进制为 55 ,是JDK 11 的内部版本号.
JVM在字节码上也设计了一套操作码助记符,使用特殊单词来标记这些数字.
ICONST 和 ALOAD 的首字母具体的数据类型, 如A 代表引用类型变量, I代表 int 类型相关操作,其他类型均是其类型的首字母.

字节码主要指令:

1.加载或存储指令
在某个栈帧中,通过指令操作数据在虚拟机栈的局部变量表与操作栈之间来回传输,常见指令如下:
(1). 将局部变量加载到操作栈中. 如ILOAD (将 int 类型的局部变量压入栈) 和ALOAD (将对象引用的局部变量压入栈)等.
(2).从操作栈顶到局部变量表. 如 ISTORE , ASTORE 等.
(3).将常量加载到操作栈顶,这是极为高频使用的指令. 如 ICONST ,BIPUSH ,LDC 等.

  • ICONST 加载的是 -1~5 的数 ( ICONST 与 BIPUSH 的加载界限)
  • BIPUSH ,即 Byte Immediate PUSH ,加载 -128~127 之间的数
  • SIPUSH, 即Short Immediate PUSH, 加载-32768~ 32767 之间的数.
  • LDC ,即Load Constant, 在-2147483648 ~ 2147483647 或者是字符串时,JVM 采用 LDC 指定压入栈中.
    走进JVM--字节码
  1. 运算指令
    对两个操作栈帧上的值进行运算,并把结果写入操作栈顶, 如IADD, IMUL 等.
  2. 类型转换指令
    显式转换两种不同的数值类型. 如 I2L, D2F 等.
  3. 对象创建与访问指令.
    根据类进行对象的创建,初始化,方法调用相关指令, 常见指令如下;
    (1). 创建对象指令. 如 NEW , NEWAEEAY 等.
    (2). 访问属性指令. 如 GETFIELD ,PUTFIELD ,GETSTATIC 等.
    (3).检查实例类型指令; 如 INSTANCEOF , CHECKCAST 等.
  4. 操作栈管理指令
    JVM提供了直接控制操作的指令,常见指令如下:
    (1). 出栈操作. 如 POP 即一个元素, POP2 即两个元素.
    (2). 复制栈顶元素并压入栈. 如 DUP.
  5. 方法调用与返回指令
    常见指令如下:
    (1)INVOKEVIRTUAL 指令: 调用对象的实例方法.
    (2) INVOKESPECIAL 指令: 调用实例初始化方法,私有方法,父类方法等.
    (3) INVOKESTATIC 指令; 调用类静态方法.
    (4) RETURN 指令: 返回 VOID 类型
  6. 同步指令
    JVM 使用方法结构中的 ACC_SYNCHRONIZED 标志同步方法,指令集中有MONITORENTER 和 MONITOREXIT 支持 synchronied 语义.

LINENUMBER 存储了字节码与源码行号的对应关系,方便调试的时候正确地定位到代码的所在行, LOCALVARIABLE 存储当前方法中使用到的局部变量表.

静态编译器如何把源码转换字节码

走进JVM--字节码

1.词法解析时通过空格分隔出单词, 操作符,控制符等信息,将其形成token信息流,传递给语法解析器,
2.在语法解析时,把词法解析得到的 token信息流按照java语法规则组装成一颗语法数,如 图虚线框中所示.
3.在语义分析阶段,需要检查关键字的使用是否合理,类型是否匹配,作用域是否正确等;
4.当语义分析完成之后,即可生成字节码.

即时编译流程

字节码必须通过类加载到JVM环境后,才可以执行,执行有三种模式:
第一: 解释执行;
第二: JIT 编译执行;
第三: JIT 编译与解释混合执行 (主流 JVM默认执行模式).
混合执行模式的优势在于解释权在启动时先解释执行,省去编译时间.随着时间推进,JVM通过热点代码统计分析,识别高频的方法调用, 循环体, 公共模块等, 基于强大的JIT动态编译技术,将热点代码装换成机器码,直接交给CPU执行.
JIT的作用是将java 字节码动态的编译成可以直接发送给处理器指令执行的机器码.
简要流程如下;
走进JVM--字节码

注意解释执行与编译执行在线上环境微妙的辩证关系:
机器在热机状态可以承受的复杂要大于冷机状态(刚启动时) ,如果以热机状态时的流量进行切流,可能使处于冷机的服务器因无法承载流量而假死,在生产环境发布过程中,以分批的方式进行发布,根据机器数量划分成多个批次,锦衣每个批次的集群数至多占整个集群的1/8.

相关文章:

  • 2022-12-23
  • 2021-04-21
  • 2021-04-08
  • 2022-01-16
  • 2021-09-21
  • 2022-02-12
  • 2021-12-26
  • 2021-07-07
猜你喜欢
  • 2022-12-23
  • 2021-07-11
  • 2022-03-04
  • 2022-12-23
  • 2021-10-04
  • 2022-12-23
相关资源
相似解决方案