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

    Reference


    字节码 核心概念

    Class文件是8位字节流,按字节对齐。之所以称为字节码,是由于每条指令都仅仅占领一个字节。全部的操作码和操作数都是按字节对齐的。

    数据结构

    Java虚拟机规范中规定。Class文件格式採用一种相似C语言结构体的伪结构来存储,它仅仅有两种数据类型

    无符号数(基本数据类型)

    主要用于描写叙述数字、索引引用、数量值、或UTF-8编码构成的字符串;
    u1 – 1个字节
    u2 – 2个字节
    u4 – 4个字节
    u8 – 8个字节

    表(复合数据类型)

    用于描写叙述有层次关系的复合结构的数据。
    习惯性以“_info”结尾

    Class文件格式

    数据类型 名称 数量
    u4 magic 1
    u2 minor_version 1
    u2 major_version 1
    u2 constant_pool_count 1
    cp_info constant_pool constant_pool_count + 1
    u2 access_flags 1
    u2 this_class 1
    u2 super_class 1
    u2 interfaces_count 1
    u2 interfaces interfaces_count
    u2 fields_count 1
    field_info fields fields_count
    u2 methods_count 1
    method_info methods methods_count
    u2 attributes_count 1
    attribute_info attributes attributes_count

    class说明

    • magic: Class文件的头4个字节,它的唯一作用是用于确认该文件是否是能被JVM接受的Class文件
    • minor_version :第5和第6字节是次版本号号
    • major_version:第7和第8字节是主版本号号

    major_version相应的JDK

    • constant_pool_count: 常量池大小

    • cp_info : 复合数据结构,是一组常量数据结构,有11种常量数据结构
      常量对象数据结构

    • access_flags :訪问标志,access_flags的计算公式为:access_flags = flagA | flagB | flagB …

    这里写图片描写叙述

    • field_info :字段表(field_info)用于描写叙述类或接口中声明的变量,它包括类变量、实例变量,但不包括方法内的局部变量和块变量。和cp_info部分不一样。cp_info由于常量类型的不一样其数据结构有11种,但field_info的结构仅仅有一种。

      (数据结构例如以下)
      字段表数据结构
      字段訪问标志。和类的訪问标志,由于修饰符不同稍有不同,具体见下图。


      这里写图片描写叙述

    • method_info:方法表集合(method_info)和字段表集合的结构是一致的,仅仅是訪问标志不同。


      这里写图片描写叙述

    • attribute_info:用于在Class文件、字段表、方法表中携带自己的属性表集合,以用于描写叙述某些场景的专有信息。
      这里写图片描写叙述
      Java程序方法体里面的代码经过javac编译器处理过后将终于字节码存储在Code属性内。抽象类或接口中的方法不存在Code属性。
      这里写图片描写叙述

    • SourceFile:SourceFile属性主要记录生成这个Class文件的源码名称,也属于可选属性,能够使用javac的-g:none或-g:source选项来关闭或要求生成这些信息。

    • LocalVariableTable:LocalVariableTable属性用于描写叙述栈帧中局部变量表中的变量与Java源码定义的变量之间的关系,可是这样的关系并不是执行时必须,默认也不会生成到Class文件里,能够通过javac中使用-g:none或-g:vars选项取消或者生成这项信息。

    • LineNumberTable:LineNumberTable属性用于描写叙述Java源码行号和字节码行号(字节码的偏移量)之间的相应关系,它不是执行时必须属性。但默认会生成到Class文件里。

      也能够在javac中使用-g:none或-g:lines选项来取消或显示生成这一部分信息。

    具体參见 Java字节码.class文件案例分析


    jvm执行浅谈

    Java虚拟机(JVM)是基于栈结构的。对于最初的main方法产生的全部的方法调用,都会在栈中产生一个帧。这些帧各自包括一组局部变量,这组局部变量就是这种方法在执行过程中所需的全部变量,包括一个指向this的引用、该方法的全部參数以及其它局部定义的变量。对于类方法(即static方法),其參数列表从0開始算起。而对于实例方法。位置0是用来存储this引用。
    class执行就是jvm顺序执行一条条保存在Code中的指令,例如以下所看到的:
    这里写图片描写叙述

    动态过程,例如以下:

    public class Demo {
        public static void foo() {
           int a = 1;
           int b = 2;
           int c = (a + b) * 5;
        }
    }

    这里写图片描写叙述

    具体參见
    - 深入理解java字节码
    - 从Java代码到字节码


    javap 反汇编

    javap是JDK自带的反汇编器。能够查看java编译器为我们生成的字节码。通过它,我们能够对比源码和字节码。从而了解非常多编译器内部的工作。
    语法:
      javap [ 命令选项 ] class…
      javap 命令用于解析类文件。其输出取决于所用的选项。

    若没有使用选项。javap 将输出传递给它的类的 public 域及方法。javap 将其输出到标准输出设备上。
    命令选项
      -help 输出 javap 的帮助信息。
      -l 输出行及局部变量表。


      -public 仅仅显示 public 类及成员。


      -protected 仅仅显示 protected 和 public 类及成员。
      -package 仅仅显示包、protected 和 public 类及成员。这是缺省设置。
      -private 显示全部类和成员。


      -s 输出内部类型签名。
      -c 输出类中各方法的未解析的代码。即构成 Java 字节码的指令。
      -verbose 输出堆栈大小、各方法的 locals 及 args 数,以及class文件的编译版本号
      -classpath[路径] 指定 javap 用来查找类的路径。假设设置了该选项,则它将覆盖缺省值或 CLASSPATH 环境变量。文件夹用冒号分隔。


      -bootclasspath[路径] 指定载入自举类所用的路径。

    缺省情况下,自举类是实现核心 Java 平台的类。位于 jrelib以下。
      -extdirs[dirs] 覆盖搜索安装方式扩展的位置。

    扩展的缺省位置是 jrelibext。

  • 相关阅读:
    Python的time模块随笔。
    生成器递归解决八皇后问题(勉强理解)
    Python历史「解密」Python底层逻辑 及Python 字节码介绍(转帖)
    可迭代(Interable),迭代器(Iterator),生成器(generator)的手记(11月26日再次修改)
    __getattr__,__setattr__,__delattr__,__getattribute__,记录
    关于property的一些记录,以及描述符(descriptor)中__get__,__set__,__delete__的属性使用。
    Python魔法方法之容器部方法(__len__,__getitem__,__setitem__,__delitem__,__missing__)(更新版本)
    Mac下PyCharm快捷键大全!(每天记住几个)
    开笔了,就写一下,hasattr,getattr,setattr。
    GUI
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/7397981.html
Copyright © 2011-2022 走看看