`
winnerbao
  • 浏览: 10444 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

一个详细的Java字节码例子

    博客分类:
  • Java
jvm 
阅读更多

[介绍]

本文给出一个java字节码的例子。 纸上得来终觉浅,绝知此事要躬行。

 

本文将详细解释一个字节码例子。 看过一些相关的文章和书籍,但是给出的例子一般都更加简化,然后给出理论解释。

我自己通过认真分析此字节码,基本上把重要部分都cover了。

 

本文的例子来自于: [KB JVM - How to print readable bytecode from class file -> An example of bytecode - java]

 

 [一些note]

关于字节码的一些note,copy到这里
java字节码与汇编程序(Assembly)有点类似.
区别在于:1)JVM没有寄存器,所有操作均在Stack上执行 2)但是有局部变量表
load : slot# --> stack
store: slot# <-- stack
const: const  --> stack
这里还有个简单的例子: [P161 Ref 1 zzm]
note:每个方法所使用的局部变量表、栈的大小在编译时确定
note:局部变量表 0 - this, 1..m m个方法参数,剩下的是可用的slot
note:调用某个方法之前,会将局部变量表准备好,因为一个线程中的所有方法共享同一个局部变量表
 

[Java Source Code]

 

public class Volatile
{
    private volatile int field = 0;

    public void increase(){
        field++;
    }


    public static void main(String[] args){
        Volatile ex = new Volatile();
        ex.increase();
    }
}

 

[ByteCode]

 

javap -verbose Volatile.class

 

下面的以BY:开头的是我的注释

都是用英文写的,因为我当时的编辑工具中文显示乱码。

D:\baoying_no_index\360CloudDisk_Compiling_Output\BaoyingCleanProject\bin>javap
-verbose Volatile


Compiled from "Volatile.java"
public class Volatile extends java.lang.Object
  SourceFile: "Volatile.java"
  minor version: 0
  major version: 50
  Constant pool:
const #1 = class        #2;     //  Volatile
const #2 = Asciz        Volatile;
const #3 = class        #4;     //  java/lang/Object
const #4 = Asciz        java/lang/Object;
const #5 = Asciz        field;
const #6 = Asciz        I;
const #7 = Asciz        <init>;
const #8 = Asciz        ()V;
const #9 = Asciz        Code;
const #10 = Method      #3.#11; //  java/lang/Object."<init>":()V
const #11 = NameAndType #7:#8;//  "<init>":()V
const #12 = Field       #1.#13; //  Volatile.field:I
const #13 = NameAndType #5:#6;//  field:I
const #14 = Asciz       LineNumberTable;
const #15 = Asciz       LocalVariableTable;
const #16 = Asciz       this;
const #17 = Asciz       LVolatile;;
const #18 = Asciz       increase;
const #19 = Asciz       main;
const #20 = Asciz       ([Ljava/lang/String;)V;
const #21 = Method      #1.#11; //  Volatile."<init>":()V
const #22 = Method      #1.#23; //  Volatile.increase:()V
const #23 = NameAndType #18:#8;//  increase:()V
const #24 = Asciz       args;
const #25 = Asciz       [Ljava/lang/String;;
const #26 = Asciz       ex;
const #27 = Asciz       SourceFile;
const #28 = Asciz       Volatile.java;


BY: https://en.wikipedia.org/wiki/Java_bytecode_instruction_listings


{
public Volatile();
  Code:
  --BY: Stack=2 max Stack size
  --BY: Locals=1, it means the Slot capacity is 1. It contains 'this' only.
  --BY: Args_size=1. only 'this' as default parameter.
   Stack=2, Locals=1, Args_size=1
   0:   aload_0  BY: push slot#0 ('this') to Stack.  after Stack: this
   1:   invokespecial   #10; //Method java/lang/Object."<init>":()V BY: invoke parent constructor. After Stack: empty
   4:   aload_0 BY: push slot#0 ('this') to Stack. Why again? A: it is required by the following(#6) putfield.(20150630)  After Stack: this
   5:   iconst_0 BY: push 0 to Stack. After Stack: (top)0, this (bottom)
   6:   putfield        #12; //Field field:I BY: assign field#12 with 0 (const #12 = Field       #1.#13; //  Volatile.field:I). After Stack: empty.
   9:   return
  LineNumberTable:
   line 9: 0
   line 11: 4
   line 9: 9

  LocalVariableTable:
   Start  Length  Slot  Name   Signature
   0      10      0    this       LVolatile;

//    public void increase(){
//        field++;
//    }
public void increase();
  Code:
   Stack=3, Locals=1, Args_size=1
   0:   aload_0  BY: push 'this' to Stack.  slot #0 is 'this'. why aload_0 is required?. A: It is used by the last ( line #7 put field) (20150630) . after: Stack:(top) this (bottom)
   1:   dup          BY: dup the top of the stack, why dup is required?. A: it is used  by the following(line #2) getfield. Although the getfile/putfied spec does not mention that it is required to put the 'this' side of the field, it is required! another example here http://cs.au.dk/~mis/dOvs/jvmspec/ref--18.html (20150630) after: Stack:(top)this, this (bottom)

   2:   getfield        #12; //Field field:I  BY: push the field #12 reference to Stack. after: Stack:(top)field #12, this(bottom)

   5:   iconst_1 BY: push 1 to Stack. Stack:(top)1, field #12, this, this(bottom)
   6:   iadd        BY: pop 2 values and push adding result back.. after: Stack:(top) value of field #12+1, this(bottom)

   7:   putfield        #12; //Field field:I  BY: pop 2 values, set field #12 value. after: Stack:(top) (bottom)
   10:  return
  LineNumberTable:
   line 14: 0
   line 15: 10

  LocalVariableTable:
   Start  Length  Slot  Name   Signature
   0      11      0    this       LVolatile;

//    public static void main(String[] args){
//        Volatile ex = new Volatile();
//        ex.increase();
//    }
//const #21 = Method      #1.#11; //  Volatile."<init>":()V
//const #22 = Method      #1.#23; //  Volatile.increase:()V
public static void main(java.lang.String[]);
  Code:
   Stack=2, Locals=2, Args_size=1
   0:   new     #1; //class Volatile BY: create a new Volatile object, after: Stack (top)ex(bottom)
   3:   dup   BY:after: Stack (top)ex,ex(bottom)
   4:   invokespecial   #21; //Method "<init>":()V BY:initialize ex, top popped for this instructino after: Stack (top)ex(bottom)
   7:   astore_1 BY: save ex to Slot #1 .after: Stack (top)ex(bottom)
   8:   aload_1 BY: save ex back to stack .after: Stack (top)ex(bottom).  Note, no change for stack, after astore_1 and aload_1, but the Slot #1 saved value 'ex' why it is required? Because the following invokation will take Slot. The Slot should prepare Slot[0] = this, Slot[1..m] as arguments. (20150630)
   9:   invokevirtual   #22; //Method increase:()V
   12:  return
  LineNumberTable:
   line 19: 0
   line 20: 8
   line 21: 12

  LocalVariableTable:
   Start  Length  Slot  Name   Signature
   0      13      0    args       [Ljava/lang/String;
   8      5      1    ex       LVolatile;


}

 

 

 

分享到:
评论

相关推荐

    java字节码例子 可以动态修改类 bcel

    这篇博客文章《java字节码例子 可以动态修改类 bcel》(链接:https://andilyliao.iteye.com/blog/899925)可能详细介绍了如何使用BCEL进行字节码操作。虽然没有具体的描述内容,但可以推测文章会涵盖以下知识点: ...

    Java字节码揭秘

    ### Java字节码揭秘 #### 一、Java体系结构概览 ...以上就是关于Java字节码及其相关概念的详细介绍,涵盖了从Java体系结构到字节码指令的具体例子,以及类加载机制的关键知识点。希望对您理解Java字节码有所帮助。

    借助jclasslib与javassist修改java class字节码

    `jclasslib`则是一款图形化的Java字节码浏览器,主要用于解析和展示Java字节码文件(`.class`文件)的内容。它可以直观地显示字节码指令和常量池中的信息,并且提供了一定程度上的编辑功能,使得用户可以直接在图形...

    一个牛逼的 Java 字节码类库!(csdn)————程序.pdf

    本文主要介绍了一个强大的Java字节码处理类库——Javaassist。 Javaassist是一个开源库,允许开发者在运行时动态地修改或者创建Java类。它提供了一种简洁的API,使得程序员无需深入了解字节码的细节就能实现复杂的...

    Java字节码(.class文件)格式详解((转载)

    Java字节码是Java程序编译后的产物,它以`.class`文件的形式存在,是Java虚拟机(JVM)能够理解和执行的二进制代码。本文将深入解析Java字节码的格式,帮助你理解其背后的运行机制。 1. **Java字节码结构** Java...

    TeaVM将Java字节码翻译成JavaScript编译器

    TeaVM是一款独特的工具,它为Java开发者提供了一种将Java字节码直接转换为JavaScript的静态编译器。这款工具的出现,使得Java应用程序能够运行在Web浏览器环境中,无需借助Java Applet或者Java Web Start等传统技术...

    java字节码框架ASM操作字节码的方法浅析

    Java字节码框架ASM是一个强大的库,它允许程序员在运行时动态生成和修改Java类和接口的字节码。ASM提供了对JVM字节码的底层访问,这使得开发者能够实现诸如AOP(面向切面编程)或者元编程等高级功能。 首先,我们...

    java 之方法调用 方法传参 值传递还是引用传递字节码

    在这个例子中,`printMessage`方法被调用,并传入一个字符串参数`"Hello, World!"`。 接下来讨论参数传递。Java采用“值传递”机制,这意味着当方法参数是基本类型(如int、char)时,实际传递的是变量的副本。对...

    探索Java虚拟机的心脏:字节码执行全解析

    Java字节码的执行过程是理解Java运行机制的核心。下面我们将详细探讨这一过程。 ##### 编译 Java源代码通过`javac`编译器被编译成字节码(`.class`文件)。编译器将高级语言转换为低级的中间表示形式——字节码。...

    C2j-Compiler:将C语言转换为Java字节码或可以直接解释执行的编译器(将C语言编译成Java字节码的编译器,也可以选择直接解释执行)

    将C语言转换为Java字节码或可以直接解释执行的编译器 作为一个学习项目 可以解释为执行大多数C或编译为Java字节码 玩具级,未添加许多功能,也没有优化 支持的 支持所有基本陈述 解释器:支持指针,数组,结构和...

    Java虚拟机(字节码的应用)1

    总的来说,理解Java字节码有助于深入洞察JVM的工作原理,包括内存管理、方法调用的细节以及异常处理的实现。这对于优化代码性能、分析和调试程序以及编写更高效的Java代码都至关重要。通过研究字节码,开发者可以更...

    Class(字节码)了解基础

    本文主要介绍了Java字节码的一些基础知识,包括Class文件格式、数据类型以及兼容性等,这些知识对于深入理解Java虚拟机(JVM)和Java程序的运行机制非常有帮助。 首先,Class文件是一种二进制格式,具有严格的格式...

    java字节码框架ASM的深入学习

    ASM是一个底层的库,它直接操作Java字节码,这使得开发者能够在运行时改变类的行为或创建新的类。本文将深入探讨ASM框架的核心概念、如何使用ASM以及一个简单的代码示例。 一、ASM框架介绍 ASM是一个开源的Java...

    Java反编译的例子

    ASP.NET是一种微软开发的Web应用程序框架,通常用于构建动态网站、Web应用和Web服务,但在这里它被用来创建一个工具来处理Java字节码。 首先,让我们理解反编译的概念。在编程中,编译是将源代码(程序员写的高级...

    通过java字节码分析学习对象初始化顺序

    通过使用像`javap`这样的工具,我们可以查看Java字节码,进一步了解这些过程。字节码是JVM直接执行的低级指令,它揭示了编译器如何将源代码转换为运行时的指令。理解字节码可以帮助我们更好地理解Java程序的工作原理...

    字节码解析示例与说明解析

    以"Demo字节码的解析.xlsx"为例,我们可能看到一个简单的Java方法的字节码分析。例如,一个简单的`add(int a, int b)`方法可能包含以下字节码: ``` 0: iload_0 // 加载局部变量a到操作数栈 1: iload_1 // 加载局部...

    3_类加载与字节码技术2

    以 HelloWorld.class 文件为例,文件头的四个字节 "ca fe ba be" 是魔数,用于识别这是一个Java字节码文件。接下来是版本号,包括主次版本号,如上述例子中的00 00 00 34代表主版本号为52(即Java 8)。类文件包含...

Global site tag (gtag.js) - Google Analytics