zoukankan      html  css  js  c++  java
  • Java字节码

    什么是字节码:

      Java的使命是一次编译,处处运行。在不同的操作系统、不同的硬件平台上,均可以不用修改代码即可顺畅地执行。

      之所以能一次编译,处处运行,有以下原因:

        1)把编译的过程分成两部分,首先无论在什么平台它会先由javac编译成通用的固定的中间形式——字节码(.class文件),然后再由解释器逐条将字节码解释为机器码来执行。

        2)JVM针对各种操作系统、平台都进行了定制

      

      Java所有的指令有200个左右,一个字节(8位)可以存储256种不同的指令信息,一个这样的字节称为字节码(bytecode)。

      在代码的执行中,JVM将字节码解释执行,屏蔽对底层操作系统的依赖;JVM也可以将字节码编译执行,如果是热点代码,会通过JIT动态地编译为机器码,提高执行效率。

    如何将源代码转化为字节码:

      我们编写好的 .java 文件是源代码文件,并不能交给机器直接执行,需要将其编译为字节码甚至是机器码文件。

      静态编译器将源码转化为字节码的过程:

    字节码的执行:

      字节码必须通过类加载过程加载到JVM环境后,才可以执行。

      执行有三种模式:

        ①:解释执行

        ②:JIT(Just In Time,即时编译器)编译执行

        ③:JIT编译与解释混合执行(主流JVM默认执行模式)

          混合执行模式的优势在于解释器在启动时先解释执行,省去编译时间。随着时间推进,JVM通过热点代码统计分析,识别高频的方法调用、循环体、公共模块等,基于强大的JIT动态编译技术,将热点代码转换为机器码,直接交给CPU执行。

          JIT的作用是将Java字节码动态地编译成可以直接发送给处理器指令执行的机器码。

    字节码主要指令:

      1、加载或存储指令

        在某个栈帧中,通过指令操作数据在虚拟机栈的局部变量表与操作栈之间来回传输,常见指令如下:

        (1):将局部变量加载到操作栈中

          ILOAD:将int类型的局部变量压入栈

          ALOAD:将对象引用的局部变量压入栈

        (2):从操作栈顶存储到局部变量表

          ISTORE、ASTORE

        (3):将常量加载到操作栈顶,这是极为高频使用的指令      

          ICONST:加载 -1 ~-5 之间的数

          BIPUSH:Byte Immediate PUSH,加载 -128~127之间的数

          SIPUSH:Short Immediate PUSH,加载 -2^15~-2^15-1之间的数

          LDC:Load Constant,在-2^31~-2^31-1之间的数 或者 是字符串时,JVM采用LDC指令压入栈中

      2、运算指令

        对两个操作栈帧上的值进行运算,并把结果写入操作栈顶,如IADD、IMUL等

      3、类型转换指令

        显示转换两种不同的数值类型,如I2L、D2F等

      4、对象创建与访问指令

        根据类进行对象的创建、初始化、方法调用相关指令,常见指令如下:

        (1):创建对象指令,如NEW、NEWARRAY等

        (2):访问属性指令,如GETFIELD、PUTFIELD、GETSTATIC等

        (3):检查实例类型指令,如INSTANCEOF、CHECKCAST等

      5、操作栈管理指令

        JVM提供了直接控制操作栈的指令,常见的指令如下:

        (1):出栈操作,POP即一个元素,POP2即两个元素

        (2):复制栈顶元素并压入栈,如DUP

        

      6、方法调用与返回指令

        INVOKEVIRTUAL:调用对象的实例方法

        INVOKESPECIAL:调用实例初始化方法、私有方法、父类方法等

        INVOKESTATIC:调用类静态方法

        RETURN:返回VOID类型

      7、同步指令

        JVM使用方法结构中的ACC_SYNCHRONIZED 标识同步方法。会在同步块的前后分别形成MONITORENTER和MONITOREXIT两个字节码指令。

        MONITORENTER:尝试获取锁,获取成功,锁计数器(monitor,位于对象头中)计数器加1

        MONITOREXIT:释放锁,锁计数器 monitor减1

    END.

  • 相关阅读:
    hash join外连接可以指定驱动表
    hash join 内连接可以指定驱动表
    R 语言命令行参数处理
    仿悦跑圈轨迹回放
    仿悦跑圈轨迹回放
    仿悦跑圈轨迹回放
    仿悦跑圈轨迹回放
    Android FrameWork学习(二)Android系统源码调试
    Android FrameWork学习(二)Android系统源码调试
    Android FrameWork学习(二)Android系统源码调试
  • 原文地址:https://www.cnblogs.com/yangyongjie/p/14574877.html
Copyright © 2011-2022 走看看