1.一个简单的java类是怎么运行的呢?
- 先让我们了解一下java语言的特性,如果编程语言分为,机械语言、汇编语言、高级语言,java可以被称作为一种高级语言,java是运行在jvm上的,jvm又是由c实现的,c最后难免翻译成汇编语言最后翻译为机械语言,我们这里知识有限只探究到jvm这层。
- 让我开始吧,先从一段简单的java的代码开始
public class TestJavaRun{
public static void main(String[] args){
int x = 10;
int y = 2;
int a = x / y;
int b = 5;
System.out.println(a + b);
}
}
执行javac TestJavaRun.java将Java类编译成jvm可运行的.class文件
用16进制打开看一下这个.class文件里面究竟长得什么样
我们知道jvm可以以把二进制文件内容翻译成java字节码变为可以操作的参数,下面我们执行javaP命令把class转化为更加刻可读的字节码文件,命令如下
javap -v TestJavaRun.class >TestJavaRun.txt
查看文件
Last modified 2020-2-11; size 423 bytes
MD5 checksum 4b9fa5546799de23d4865ab190c396f3
Compiled from "TestJavaRun.java"
public class TestJavaRun
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #5.#14 // java/lang/Object."<init>":()V
#2 = Fieldref #15.#16 // java/lang/System.out:Ljava/io/PrintStream;
#3 = Methodref #17.#18 // java/io/PrintStream.println:(I)V
#4 = Class #19 // TestJavaRun
#5 = Class #20 // java/lang/Object
#6 = Utf8 <init>
#7 = Utf8 ()V
#8 = Utf8 Code
#9 = Utf8 LineNumberTable
#10 = Utf8 main
#11 = Utf8 ([Ljava/lang/String;)V
#12 = Utf8 SourceFile
#13 = Utf8 TestJavaRun.java
#14 = NameAndType #6:#7 // "<init>":()V
#15 = Class #21 // java/lang/System
#16 = NameAndType #22:#23 // out:Ljava/io/PrintStream;
#17 = Class #24 // java/io/PrintStream
#18 = NameAndType #25:#26 // println:(I)V
#19 = Utf8 TestJavaRun
#20 = Utf8 java/lang/Object
#21 = Utf8 java/lang/System
#22 = Utf8 out
#23 = Utf8 Ljava/io/PrintStream;
#24 = Utf8 java/io/PrintStream
#25 = Utf8 println
#26 = Utf8 (I)V
{
public TestJavaRun();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 1: 0
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=5, args_size=1
0: bipush 10
2: istore_1
3: iconst_2
4: istore_2
5: iload_1
6: iload_2
7: idiv
8: istore_3
9: iconst_5
10: istore 4
12: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
15: iload_3
16: iload 4
18: iadd
19: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
22: return
LineNumberTable:
line 3: 0
line 4: 3
line 5: 5
line 6: 9
line 7: 12
line 8: 22
}
SourceFile: "TestJavaRun.java"
可以看到文件内容为java字节码指令
3.看到这里,我们需要思考当jvm解释完这些内容又是如何运行的呢
首先jvm把.class文件中的类的信息加载到方法区与堆内存中,这里属于线程共享部分,之后jvm创建线程执行代码,这里是jvm的线程独享区,这里
有“虚拟机栈”、“本地方法栈”、“程序记数器”,这里当代码执行到某个指令码时可以理解为是在“虚拟机栈”或者执行本地方法时在“本地方法栈”中实现逻辑,我们都知道cpu在执行任务时会有多线程争抢的问题,这里“程序技数器”会记录当前执行的位置,下次重新执行时从哪里开始。