`

慕然回首,却发现JVM字节码原来如此

    博客分类:
  • JVM
 
阅读更多

一、万能的Hello World, 现身吧:

[html]   view plain copy
  1. package com.jian;  
  2. public class Test {  
  3.     public static void main(String[] args) {  
  4.   
  5.         System.out.println("Hello World");  
  6.     }  
  7. }  


二、有一神器叫java, 在jdk的bin下, 不管你会不会用,你都得用,只有他才能驯服Hello World, 将其转换形态,变成传说中的字节码,class文件。

Hello World为什么神奇,多少世纪来无能能解,现在我们将它转换成了clss形态,他目前神力尽失,只能任由我们处置了。

还等什么,拿出javap解剖刀,让我们看看它的真身吧:

[html]   view plain copy
  1. javap.exe -v C:\workspace\j2ee\Test\bin\com\jian\Test.class  


怎么样,怎么样,五脏六腹全都出来了吧,哈哈哈。。。

[html]   view plain copy
  1. Classfile /C:/workspace/j2ee/Test/bin/com/jian/Test.class  
  2.   Last modified 2012-1-6; size 533 bytes  
  3.   MD5 checksum c3f1f6231f3171633175804c46502e5c  
  4.   Compiled from "Test.java"  
  5. public class com.jian.Test  
  6.   SourceFile: "Test.java"  
  7.   minor version: 0  
  8.   major version: 51  
  9.   flags: ACC_PUBLIC, ACC_SUPER  
  10. Constant pool:  
  11.    #1  =  Class               #2             //  com/jian/Test  
  12.    #2  =  Utf8                com/jian/Test  
  13.    #3  =  Class               #4             //  java/lang/Object  
  14.    #4  =  Utf8                java/lang/Object  
  15.    #5  =  Utf8                 < init >   
  16.    #6  =  Utf8                ()V  
  17.    #7  =  Utf8                Code  
  18.    #8  =  Methodref           #3.#9          //  java/lang/Object." < init > ":()V  
  19.    #9  =  NameAndType         #5:#6          //  " < init > ":()V  
  20.   #10  =  Utf8                LineNumberTable  
  21.   #11  =  Utf8                LocalVariableTable  
  22.   #12  =  Utf8                this  
  23.   #13  =  Utf8                Lcom/jian/Test;  
  24.   #14  =  Utf8                main  
  25.   #15  =  Utf8                ([Ljava/lang/String;)V  
  26.   #16  =  Fieldref            #17.#19        //  java/lang/System.out:Ljava/io/PrintStream;  
  27.   #17  =  Class               #18            //  java/lang/System  
  28.   #18  =  Utf8                java/lang/System  
  29.   #19  =  NameAndType         #20:#21        //  out:Ljava/io/PrintStream;  
  30.   #20  =  Utf8                out  
  31.   #21  =  Utf8                Ljava/io/PrintStream;  
  32.   #22  =  String              #23            //  Hello World  
  33.   #23  =  Utf8                Hello World  
  34.   #24  =  Methodref           #25.#27        //  java/io/PrintStream.println:(Ljava/lang/String;)V  
  35.   #25  =  Class               #26            //  java/io/PrintStream  
  36.   #26  =  Utf8                java/io/PrintStream  
  37.   #27  =  NameAndType         #28:#29        //  println:(Ljava/lang/String;)V  
  38.   #28  =  Utf8                println  
  39.   #29  =  Utf8                (Ljava/lang/String;)V  
  40.   #30  =  Utf8                args  
  41.   #31  =  Utf8                [Ljava/lang/String;  
  42.   #32  =  Utf8                SourceFile  
  43.   #33  =  Utf8                Test.java  
  44. {  
  45.   public com.jian.Test();  
  46.     flags: ACC_PUBLIC  
  47.     Code:  
  48.       stack = 1 locals = 1 args_size = 1   
  49.          0: aload_0  
  50.          1: invokespecial #8                  // Method java/lang/Object."< init > ":()V  
  51.          4: return  
  52.       LineNumberTable:  
  53.         line 4: 0  
  54.       LocalVariableTable:  
  55.         Start  Length  Slot  Name   Signature  
  56.                0       5     0  this   Lcom/jian/Test;  
  57.   
  58.   public static void main(java.lang.String[]);  
  59.     flags: ACC_PUBLIC, ACC_STATIC  
  60.     Code:  
  61.       stack = 2 locals = 1 args_size = 1   
  62.          0: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;  
  63.          3: ldc           #22                 // String Hello World  
  64.          5: invokevirtual #24                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V  
  65.          8: return  
  66.       LineNumberTable:  
  67.         line 6: 0  
  68.         line 7: 8  
  69.       LocalVariableTable:  
  70.         Start  Length  Slot  Name   Signature  
  71.                0       9     0  args   [Ljava/lang/String;  
  72. }  


此结构非常清晰,具体请参照JVM规范,今天我们主要分析Hello World是怎么出来的。。。

字节码的执行主要有三个栈上:操作数栈, 本地变量表,操作栈帧, 操作数栈是记录各种位置信息的,不用管他,咱要要看 本地变量表,操作栈帧:

[html]   view plain copy
  1. public com.jian.Test();  
  2.     flags: ACC_PUBLIC  
  3.     Code:  
  4.       stack = 1 locals = 1 args_size = 1   
  5.          0: aload_0  
  6.          1: invokespecial #8                  // Method java/lang/Object."< init > ":()V  
  7.          4: return  
  8.       LineNumberTable:  
  9.         line 4: 0  
  10.       LocalVariableTable:  
  11.         Start  Length  Slot  Name   Signature  
  12.                0       5     0  this   Lcom/jian/Test;  


三、看看这一段 ,本地方法表只一个值,是什么,那就是大名鼎鼎的this, 看看Code处三句话:

第一句,aload_0, 0是什么,就是本地方法表中的slot0, 我kao,一上来就把this加载上来,加载到哪去了呢?看不到吧,当然看不到,这上面没显示出来,在每个方法调用时,jvm都会创建一个操作栈帧,aload_0就是

把本地方法表中的0 slot放到操作栈帧顶部,

第二句话干什么呢,invokespecial #8, 看看后面的注释吧,它竟然执行了Object的init方法,随便他了,管不了他,他是JVM,它想执行啥就让他执行吧。

第三句话就不说了,都return了。。。此操作栈帧就到此灭亡。。来世再见。

 

四、Hello World,轮到你了:

[html]   view plain copy
  1. public static void main(java.lang.String[]);  
  2.     flags: ACC_PUBLIC, ACC_STATIC  
  3.     Code:  
  4.       stack = 2 locals = 1 args_size = 1   
  5.          0: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;  
  6.          3: ldc           #22                 // String Hello World  
  7.          5: invokevirtual #24                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V  
  8.          8: return  
  9.       LineNumberTable:  
  10.         line 6: 0  
  11.         line 7: 8  
  12.       LocalVariableTable:  
  13.         Start  Length  Slot  Name   Signature  
  14.                0       9     0  args   [Ljava/lang/String;  

看到了吗,要让控制台打出惊世骇俗的Hello World,丫就4条JVM指令,

第一句:getstatic #16   ,看到了吧。。丫往操作帧中放了什么,kao,就两个静态域的引用 ,system.out和PrintStream

第二句:ldc #22     Hello World, 考,这货怎么会是#22, 它竟然在常量池中,好吧,明白了吧,它竟然躲起来了,但我们还是将他揪出来了,放入操作帧吧,看他能耍什么花招

第三句: invokevirtual #24  看到了吗,这才是神器,void PrintStream.println(String),..   让操作栈桢发威吧,有了他,传说中的Hello World立马出现在万人瞩目的控制台了

第四句:完事收工,再见。。。

分享到:
评论

相关推荐

    JVM 字节码从入门到精通

    Java虚拟机(JVM)是Java程序的运行环境,它负责解释和执行Java字节码文件。字节码文件是用.class扩展名标识的文件,它们是Java源代码经过编译器编译后生成的中间代码形式。这种设计允许Java程序具有跨平台的特性,...

    jvm字节码自动加载

    在Java虚拟机(JVM)中,字节码自动加载是一项关键功能,它使得Java程序能够在运行时动态地发现和加载类。字节码是由Java源代码编译而成的二进制格式,它包含了类和接口的信息。了解JVM如何自动加载字节码对于深入...

    jvm字节码与类的加载.xmind

    自己总结的jvm中字节码与类的加载的笔记,绘制了详细的思维导图,每个思维导图中均有详细的博文解释,方便大家学习和理解,免费分享给大家。适合jvm的爱好者和学习者

    深入理解JVM.rar

    每个使用Java的开发者都知道Java字节码是在JRE中运行,而JVM则是JRE中的核心组成部分,承担分析和执行Java字节码的工作,而Java程序员通常并不需要深入了解JVM运行情况就可以开发出大型应用和类库。尽管如此,如果你...

    jvm-callgraph,jvm字节码的调用图生成器.zip

    《深入解析JVM字节码调用图生成器——基于jvm-callgraph开源项目》 在Java虚拟机(JVM)的世界里,理解和优化代码执行性能是至关重要的。为了达到这一目的,开发者需要深入理解程序的运行时行为,其中就包括了类与...

    JVM优化3(Tomcat参数调优,JVM参数调优,jvm字节码,代码优化).pdf

    本篇文件内容主要介绍了JVM优化的第三部分,重点围绕Tomcat参数调优、JVM参数调优、JVM字节码优化以及代码优化等几个方面。下面是针对这些知识点的详细解释: 1. Tomcat参数调优 在Tomcat参数调优部分,首先介绍了...

    Swift-to-JVM字节码编译器JetANTLR.zip

    Jet 是 Swift-to-JVM 字节码编译器,为 Java 8 Runtime 而准备。Jet 使用 ANTLR 编写。 标签:JetANTLR

    深入解析Java中的JVM字节码:原理、作用与代码示例

    JVM字节码是Java程序跨平台运行的关键,它不仅保证了Java程序的可移植性,还通过JIT编译技术提高了程序的执行效率。理解JVM字节码的原理和构成对于Java开发者来说至关重要,它有助于我们深入理解Java程序的运行机制...

    JVM优化3(Tomcat参数调优,JVM参数调优,jvm字节码,代码优化).zip

    这个压缩包文件"JVM优化3(Tomcat参数调优,JVM参数调优,jvm字节码,代码优化).zip"显然包含了关于如何优化Java应用程序运行效率的四个主要方面:Tomcat服务器的参数调整、JVM参数调优、JVM字节码理解和优化以及代码...

    字节码实战包含class,字节码.zip

    在Java编程语言中,字节码(Bytecode)扮演着至关重要的角色,它是JVM(Java虚拟机)理解和执行程序的基础。"字节码实战"的主题深入探讨了字节码的概念、生成以及如何利用它来优化Java应用程序。下面将详细阐述相关...

    深入了解JVM字节码增强技术

    深入了解JVM字节码增强技术 JVM字节码增强技术是Java开发中的一种技术,它可以在Java字节码生成之后,对其进行修改,增强其功能。这种技术可以减少冗余代码,提高性能等。 主要知识点: 1. Java字节码增强的定义...

    JVM中文指令手册.pdf

    JVM指令手册详细记录了JVM的所有操作码(opcode),也就是字节码指令。这些指令是给JVM解释器或者即时编译器(JIT)使用的低级指令集。在JVM上运行的Java程序会被编译成一系列指令,然后由JVM执行。 从给定文件的...

    JVM指令码表.zip

    Java虚拟机(JVM)是Java程序运行的核心,它通过解析和执行字节码来实现程序的运行。字节码是一系列二进制指令,这些指令在类文件中以16进制形式表示,每条指令占据一个或多个字节。`JVM指令码表.zip`包含的`JVM指令...

    Java lambda表达式和JVM字节码功能详解.pdf

    Java字节码和Lambda表达式之间的关系体现在JVM的LambdaMetafactory机制上,它负责在运行时动态生成对应的函数式类。Lambda表达式在编译后的`.class`文件中,通常以`ClassName$Lambda$1`这样的形式命名,其中`...

    JVM 完整深入解析.pdf

    程序计数器是当前线程所执行的字节码的行号指示器,是线程私有的内存区域。由于Java是多线程并发执行的,每个线程都需要有一个独立的程序计数器,以便记录线程切换后继续执行的位置。 #### 虚拟机栈 虚拟机栈是Java...

    JVM-字节码文件加载过程.md

    JVM-字节码文件加载过程.md

    jvm-java字节码规则.pdf

    Java虚拟机(JVM)是运行Java程序的核心引擎,负责解释、执行Java字节码。Java字节码是一种中间语言,可以在任何安装了JVM的机器上运行,使得Java程序具有跨平台的能力。Java源代码在编译成.class文件时,会被编译器...

    轻松看懂Java字节码.pdf

    开发者能够通过分析字节码来发现潜在的问题,改进程序性能,或者增强应用的安全性。 在实际分析Java字节码时,可以利用javap工具查看生成的字节码指令,例如以Main.class文件为例,会看到一系列的数字和字符组合。...

    java字节码加密

    在Java中,字节码(Bytecode)是程序经过编译后的中间表示,可以直接由Java虚拟机(JVM)执行。由于字节码是明文的,如果直接暴露,可能会导致知识产权泄露,因此对其进行加密至关重要。 字节码加密通常包括以下几...

Global site tag (gtag.js) - Google Analytics