一、万能的Hello World, 现身吧:
-
package com.jian;
-
public class Test {
-
public static void main(String[] args) {
-
-
System.out.println("Hello World");
-
}
-
}
二、有一神器叫java,
在jdk的bin下, 不管你会不会用,你都得用,只有他才能驯服Hello World, 将其转换形态,变成传说中的字节码,class文件。
Hello World为什么神奇,多少世纪来无能能解,现在我们将它转换成了clss形态,他目前神力尽失,只能任由我们处置了。
还等什么,拿出javap解剖刀,让我们看看它的真身吧:
-
javap.exe -v C:\workspace\j2ee\Test\bin\com\jian\Test.class
怎么样,怎么样,五脏六腹全都出来了吧,哈哈哈。。。
-
Classfile /C:/workspace/j2ee/Test/bin/com/jian/Test.class
-
Last modified 2012-1-6; size 533 bytes
-
MD5 checksum c3f1f6231f3171633175804c46502e5c
-
Compiled from "Test.java"
-
public class com.jian.Test
-
SourceFile: "Test.java"
-
minor version: 0
-
major version: 51
-
flags: ACC_PUBLIC, ACC_SUPER
-
Constant pool:
-
#1
=
Class
#2 // com/jian/Test
-
#2
=
Utf8
com/jian/Test
-
#3
=
Class
#4 // java/lang/Object
-
#4
=
Utf8
java/lang/Object
-
#5
=
Utf8
<
init
>
-
#6
=
Utf8
()V
-
#7
=
Utf8
Code
-
#8
=
Methodref
#3.#9 // java/lang/Object."
<
init
>
":()V
-
#9
=
NameAndType
#5:#6 // "
<
init
>
":()V
-
#10
=
Utf8
LineNumberTable
-
#11
=
Utf8
LocalVariableTable
-
#12
=
Utf8
this
-
#13
=
Utf8
Lcom/jian/Test;
-
#14
=
Utf8
main
-
#15
=
Utf8
([Ljava/lang/String;)V
-
#16
=
Fieldref
#17.#19 // java/lang/System.out:Ljava/io/PrintStream;
-
#17
=
Class
#18 // java/lang/System
-
#18
=
Utf8
java/lang/System
-
#19
=
NameAndType
#20:#21 // out:Ljava/io/PrintStream;
-
#20
=
Utf8
out
-
#21
=
Utf8
Ljava/io/PrintStream;
-
#22
=
String
#23 // Hello World
-
#23
=
Utf8
Hello World
-
#24
=
Methodref
#25.#27 // java/io/PrintStream.println:(Ljava/lang/String;)V
-
#25
=
Class
#26 // java/io/PrintStream
-
#26
=
Utf8
java/io/PrintStream
-
#27
=
NameAndType
#28:#29 // println:(Ljava/lang/String;)V
-
#28
=
Utf8
println
-
#29
=
Utf8
(Ljava/lang/String;)V
-
#30
=
Utf8
args
-
#31
=
Utf8
[Ljava/lang/String;
-
#32
=
Utf8
SourceFile
-
#33
=
Utf8
Test.java
-
{
-
public com.jian.Test();
-
flags: ACC_PUBLIC
-
Code:
-
stack
=
1
,
locals
=
1
,
args_size
=
1
-
0: aload_0
-
1: invokespecial #8 // Method java/lang/Object."<
init
>
":()V
-
4: return
-
LineNumberTable:
-
line 4: 0
-
LocalVariableTable:
-
Start Length Slot Name Signature
-
0 5 0 this Lcom/jian/Test;
-
-
public static void main(java.lang.String[]);
-
flags: ACC_PUBLIC, ACC_STATIC
-
Code:
-
stack
=
2
,
locals
=
1
,
args_size
=
1
-
0: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream;
-
3: ldc #22 // String Hello World
-
5: invokevirtual #24 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
-
8: return
-
LineNumberTable:
-
line 6: 0
-
line 7: 8
-
LocalVariableTable:
-
Start Length Slot Name Signature
-
0 9 0 args [Ljava/lang/String;
-
}
此结构非常清晰,具体请参照JVM规范,今天我们主要分析Hello World是怎么出来的。。。
字节码的执行主要有三个栈上:操作数栈, 本地变量表,操作栈帧, 操作数栈是记录各种位置信息的,不用管他,咱要要看 本地变量表,操作栈帧:
-
public com.jian.Test();
-
flags: ACC_PUBLIC
-
Code:
-
stack
=
1
,
locals
=
1
,
args_size
=
1
-
0: aload_0
-
1: invokespecial #8 // Method java/lang/Object."<
init
>
":()V
-
4: return
-
LineNumberTable:
-
line 4: 0
-
LocalVariableTable:
-
Start Length Slot Name Signature
-
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,轮到你了:
-
public static void main(java.lang.String[]);
-
flags: ACC_PUBLIC, ACC_STATIC
-
Code:
-
stack
=
2
,
locals
=
1
,
args_size
=
1
-
0: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream;
-
3: ldc #22 // String Hello World
-
5: invokevirtual #24 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
-
8: return
-
LineNumberTable:
-
line 6: 0
-
line 7: 8
-
LocalVariableTable:
-
Start Length Slot Name Signature
-
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立马出现在万人瞩目的控制台了
第四句:完事收工,再见。。。
分享到:
相关推荐
Java虚拟机(JVM)是Java程序的运行环境,它负责解释和执行Java字节码文件。字节码文件是用.class扩展名标识的文件,它们是Java源代码经过编译器编译后生成的中间代码形式。这种设计允许Java程序具有跨平台的特性,...
在Java虚拟机(JVM)中,字节码自动加载是一项关键功能,它使得Java程序能够在运行时动态地发现和加载类。字节码是由Java源代码编译而成的二进制格式,它包含了类和接口的信息。了解JVM如何自动加载字节码对于深入...
自己总结的jvm中字节码与类的加载的笔记,绘制了详细的思维导图,每个思维导图中均有详细的博文解释,方便大家学习和理解,免费分享给大家。适合jvm的爱好者和学习者
每个使用Java的开发者都知道Java字节码是在JRE中运行,而JVM则是JRE中的核心组成部分,承担分析和执行Java字节码的工作,而Java程序员通常并不需要深入了解JVM运行情况就可以开发出大型应用和类库。尽管如此,如果你...
《深入解析JVM字节码调用图生成器——基于jvm-callgraph开源项目》 在Java虚拟机(JVM)的世界里,理解和优化代码执行性能是至关重要的。为了达到这一目的,开发者需要深入理解程序的运行时行为,其中就包括了类与...
本篇文件内容主要介绍了JVM优化的第三部分,重点围绕Tomcat参数调优、JVM参数调优、JVM字节码优化以及代码优化等几个方面。下面是针对这些知识点的详细解释: 1. Tomcat参数调优 在Tomcat参数调优部分,首先介绍了...
Jet 是 Swift-to-JVM 字节码编译器,为 Java 8 Runtime 而准备。Jet 使用 ANTLR 编写。 标签:JetANTLR
JVM字节码是Java程序跨平台运行的关键,它不仅保证了Java程序的可移植性,还通过JIT编译技术提高了程序的执行效率。理解JVM字节码的原理和构成对于Java开发者来说至关重要,它有助于我们深入理解Java程序的运行机制...
这个压缩包文件"JVM优化3(Tomcat参数调优,JVM参数调优,jvm字节码,代码优化).zip"显然包含了关于如何优化Java应用程序运行效率的四个主要方面:Tomcat服务器的参数调整、JVM参数调优、JVM字节码理解和优化以及代码...
在Java编程语言中,字节码(Bytecode)扮演着至关重要的角色,它是JVM(Java虚拟机)理解和执行程序的基础。"字节码实战"的主题深入探讨了字节码的概念、生成以及如何利用它来优化Java应用程序。下面将详细阐述相关...
深入了解JVM字节码增强技术 JVM字节码增强技术是Java开发中的一种技术,它可以在Java字节码生成之后,对其进行修改,增强其功能。这种技术可以减少冗余代码,提高性能等。 主要知识点: 1. Java字节码增强的定义...
JVM指令手册详细记录了JVM的所有操作码(opcode),也就是字节码指令。这些指令是给JVM解释器或者即时编译器(JIT)使用的低级指令集。在JVM上运行的Java程序会被编译成一系列指令,然后由JVM执行。 从给定文件的...
Java虚拟机(JVM)是Java程序运行的核心,它通过解析和执行字节码来实现程序的运行。字节码是一系列二进制指令,这些指令在类文件中以16进制形式表示,每条指令占据一个或多个字节。`JVM指令码表.zip`包含的`JVM指令...
Java字节码和Lambda表达式之间的关系体现在JVM的LambdaMetafactory机制上,它负责在运行时动态生成对应的函数式类。Lambda表达式在编译后的`.class`文件中,通常以`ClassName$Lambda$1`这样的形式命名,其中`...
程序计数器是当前线程所执行的字节码的行号指示器,是线程私有的内存区域。由于Java是多线程并发执行的,每个线程都需要有一个独立的程序计数器,以便记录线程切换后继续执行的位置。 #### 虚拟机栈 虚拟机栈是Java...
JVM-字节码文件加载过程.md
Java虚拟机(JVM)是运行Java程序的核心引擎,负责解释、执行Java字节码。Java字节码是一种中间语言,可以在任何安装了JVM的机器上运行,使得Java程序具有跨平台的能力。Java源代码在编译成.class文件时,会被编译器...
开发者能够通过分析字节码来发现潜在的问题,改进程序性能,或者增强应用的安全性。 在实际分析Java字节码时,可以利用javap工具查看生成的字节码指令,例如以Main.class文件为例,会看到一系列的数字和字符组合。...
在Java中,字节码(Bytecode)是程序经过编译后的中间表示,可以直接由Java虚拟机(JVM)执行。由于字节码是明文的,如果直接暴露,可能会导致知识产权泄露,因此对其进行加密至关重要。 字节码加密通常包括以下几...