JVM-4-字节码

概述

  • 字节码采用Big-Endian,是Spark、PowerPC等处理器的默认字节序;x86则是用Little-Endian
jvm-001.jpg
  • 字节码文件采用一种类似于C语言结构体的伪结构来存储数据,只有两种数据类型:无符号数和表
    • 无符号数
      • 基本数据类型,以u1,u2,u4,u8分别代表1,2,4,8字节的无符号数
      • 可用来描述数字、索引引用、数量值或者按UTF-8编码构成字符串值
      • 由多个无符号数或者其他表作为数据项构成的复合数据类型
      • 习惯性地以“_info”结尾
      • 整个Class文件本质上也就是一张表

文件结构

ClassFile {
    u4             magic; # 0xCAFEBABE
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        contant_pool[constant_pool_count – 1]; # 之所以-1,是因为#0被做他用了
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    u2             fields_count;
    field_info     fields[fields_count];
    u2             methods_count;
    method_info    methods[methods_count];
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}
magic, minor_version, major_version
    specifies information about the version of the class,  and the version of the JDK this class was compiled for
constant_pool
    similar to a symbol table although it contains more data this is described in more detail below
access_flags
    provides the list of modifiers for this class
this_class
    index into the constant_pool providing the fully qualified name of this class i.e. org/jamesdbloom/foo/Bar
super_class
    index into the constant_pool providing a symbolic reference to the super class i.e. java/lang/Object
interfaces
    array of indexes into the constant_pool providing a symbolic references to all interfaces that have been implemented
fields
    array of indexes into the constant_pool giving a complete description of each field
methods
    array of indexes into the constant_pool giving a complete description of each method signature, if the method is not abstract or native then the bytecode is also present
attributes
    array of different value that provide additional information about the class including any annotations with RetentionPolicy.CLASS or RetentionPolicy.RUNTIME

结构详解

  • 魔数
    • 标识class文件
  • 大小版本
    • major_version.minor_version合在一起为class文件版本,编译器产生,如59.0,与JDK版本相关
  • 常量池
    • 相同类型值在常量池中归一,以索引供外部引用,缩减字节码文件大小,便于网络传输的初衷
    • 逻辑类型:字面量(literal) + 符号引用(symbolic reference)
    • 常量池中装常量,每个常量都是一个表,一共14种常量(JDk 7之前只有前11种)
image.png

image.png

访问标识

名称 描述
ACC_PUBLIC 0x0001 public
ACC_FINAL 0x0010 final,不可被继承
ACC_SUPER 0x0020 兼容早期编译器,新编译器均设该标记,invokespecial指令会对子类方法做特定处理
ACC_INTERFACE 0x0200 接口,需同时设置ABSTRACT
ACC_ABSTRACT 0x0400 抽象类
ACC_SYNTHETIC 0x1000 synthetic,编译器产生
ACC_ANNOTATION 0x2000 注解,需同时INTERFACE和ABSTRACT
ACC_ENUM 0x4000 枚举
  • 多项值:或运算
    • PUBLIC+SUPER 0x0021

字段表

  • 类变量,实例变量,但不含继承变量,不含局部变量
  • Z(boolean) B C S I J(long) F D V L(object)
名称 类型 描述
access_flags u2 见属性访问标识
name_index u2 名称索引
descriptor_index u2 描述符索引
attributes_count u2 属性个数
attributes[attributes_count] attribute_info 属性集合
  • 属性访问标识
名称 描述
ACC_PUBLIC 0x0001 public
ACC_PRIVATE 0x0002 private
ACC_PROTECTED 0x0004 protected
ACC_STATIC 0x0008 static
ACC_FIANL 0x0010 final
ACC_VOLATILE 0x0040 volatile,直接读写内存,不可被缓存;与FINAL互斥
ACC_TRANSIENT 0x0080 transient
ACC_SYNTHETIC 0x1000 synthetic
ACC_ENUM 0x4000 enum

方法表

名称 类型 描述
access_flags u2 见方法访问标识
name_index u2 名称索引
descriptor_index u2 描述符索引
attributes_count u2 属性个数
attributes[attributes_count] attribute_info 属性集合
  • 方法访问标识
名称 描述
ACC_PUBLIC 0x0001 public
ACC_PRIVATE 0x0002 private
ACC_PROTECTED 0x0004 protected
ACC_STATIC 0x0008 static
ACC_FIANL 0x0010 final
ACC_SYNCHRONIZED 0x0040 synchronized
ACC_BRIDGE 0x0080 桥接方法,泛型时出现过
ACC_VARARGS 0x0080 含不定参数
ACC_NATIVE 0x0080 native
ACC_ABSTRACT 0x0080 abstract
ACC_STRICTFP 0x1000 strictfp
ACC_SYNTHETIC 0x4000 synthetic,编译器产生,如<init>,<clinit>

字节码命令

# 变量操作
aload_n # 本地变量数组->操作数栈 a代表对象引用,n代表本地变量数组索引
iload # int
lload # long
fload # float
dload # double
ldc # 运行时常量池常量->操作数栈
getstatic # 运行时常量池静态变量->操作数栈

# 方法
invokedynamic
invokeinterface
invokespecial # 实例初始化,私有方法,父类方法
invokestatic
invokevirtual # 普通实例方法

# return语句
return:void
ireturn:int
lreturn:long
freturn:float
dreturn:double
areturn:object reference

# java源码
Object foo = new Object();
# 字节码
 0: new #2           // Class java/lang/Object
 1: dup
 2: invokespecial #3 // Method java/lang/Object:"<init>"( ) V
 
 0 # 堆中开了块内存,返回对象引用至操作数栈
 1 # 复制栈顶对象引用,塞入栈顶
 3 # 对象初始化,消耗栈顶对象引用(作为参数)
 # 留下的那个栈顶对象引用,就是初始化好的对象引用

字节码文件例子

package some;
public class SimpleClass {
    private int m;
    public int inc() {
        return m + 1;
    }
}
cafe babe 0000 0034 0016 0700 0201 0010
736f 6d65 2f53 696d 706c 6543 6c61 7373
0700 0401 0010 6a61 7661 2f6c 616e 672f
4f62 6a65 6374 0100 016d 0100 0149 0100
063c 696e 6974 3e01 0003 2829 5601 0004
436f 6465 0a00 0300 0b0c 0007 0008 0100
0f4c 696e 654e 756d 6265 7254 6162 6c65
0100 124c 6f63 616c 5661 7269 6162 6c65
5461 626c 6501 0004 7468 6973 0100 124c
736f 6d65 2f53 696d 706c 6543 6c61 7373
3b01 0003 696e 6301 0003 2829 4909 0001
0013 0c00 0500 0601 000a 536f 7572 6365
4669 6c65 0100 1053 696d 706c 6543 6c61
7373 2e6a 6176 6100 2100 0100 0300 0000
0100 0200 0500 0600 0000 0200 0100 0700
0800 0100 0900 0000 2f00 0100 0100 0000
052a b700 0ab1 0000 0002 000c 0000 0006
0001 0000 0003 000d 0000 000c 0001 0000
0005 000e 000f 0000 0001 0010 0011 0001
0009 0000 0031 0002 0001 0000 0007 2ab4
0012 0460 ac00 0000 0200 0c00 0000 0600
0100 0000 0700 0d00 0000 0c00 0100 0000
0700 0e00 0f00 0000 0100 1400 0000 0200
15

javap -v -p -s -sysinfo -constant some/SimpleClass.class

package some;
public class SimpleClass {
    public int a = 1;//这个1并不会出现在常量池中,而a以Filedref出现
    final int b = 3;//这个3会以Integer表的身份出现在常量池中,b也以Fieldref出现
    public void sayHello() {
                final int c = 10;//只有c以Utf8出现,10并没有出现(这个final待究)
        System.out.println(c);
        System.out.println("Hello");
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,306评论 4 370
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,657评论 2 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,928评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,688评论 0 220
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,105评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,024评论 1 225
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,159评论 2 318
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,937评论 0 212
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,689评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,851评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,325评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,651评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,364评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,192评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,985评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,154评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,955评论 2 279

推荐阅读更多精彩内容