Java代码是如何在JVM中运行的

在前面我们讨论了JVM内存模型和Java类的编译加载执行过程。接下来我,我们通过一个案例进一步加深对JVM的认识。源代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
public class JVMcase {
// final修饰的常量
public final static String MAN_SEX_TYPE = "man";

// 静态变量
public static String WOMAN_SEX_TYPE = "woman";

public static void main(String[] args) {
Student stu = new Student();
stu.setName("nick");
stu.setSexType(MAN_SEX_TYPE);
stu.setAgen(20);

JVMCase jvmcase = new JVMCase();

// 调用静态方法
print(stu);
// 调用非静态方法
jvmcase.sayHello(stu);
}

// 常规静态方法
public static void print(Student stu) {
System.out.println("name: " + stu.getName() + "; sex: " + stu.getSexType() + "; age: " + stu.getAge());
}

// 非静态方法
public void sayHello(Student stu) {
System.out.println(stu.getName() + "sya: hello");
}
}

class Student{
String name;
String sexType;
int age;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getSexType() {
return sexType;
}

public void setSexType(String sexType) {
hits.sexType = sexType;
}

public int getAget() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}

当我们通过Java运行以上代码时,JVM的整个处理过程如下:

一、申请内存

JVM第一步是通过配置参数或者默认配置参数向操作系统申请内存空间,操作系统会根据申请的内存大小找到具体的内存分配表,然后把内存段的起始地址和终止地址分配给JVM。接下来JVM就会进行内部分配。

二、内部分配

在获得内存空间后,JVM就会根据配置参数分配堆、方法区以及栈的内存大小。

三、加载、链接

完成内部分配后,JVM会将class文件加载到内存中,并进行验证、准备、解析等操作。其中,在准备阶段会为类的静态变量分配内存,初始化为系统的初始值。

image-20200920163103371

四、初始化

完成链接操作后,JVM会进行最后一个初始化阶段。在这个阶段中,JVM首先会执行构造器方法。此时,静态变量的初始值(null)会被初始化为用户自定义的值。

image-20200920163907881

五、执行方法

初始化完成后,JVM就会启动main线程,执行main方法,开始第一行代码的执行。此时,首先会在堆内存中创建一个Student对象,Student对象的引用就存放在栈中。

image-20200920164529917

接着会创建一个JVMCase对象,调用sayHello非静态方法,sayHello方法属于对象JVMCase,此时sayHello方法入栈,并通过栈中的Student引用调用堆中的Student对象;

image-20200920165305309

最后,调用静态方法print,print静态方法属于JVMCase类,是从静态方法中获取,之后放入到栈中,也是通过栈中的student引用调用堆中student对象。

image-20200920165445131

六、小结

在这篇文章中,我们主要讨论了Java代码是如何在JVM中运行的,这个过程包括:

  • 申请内存
  • 内部分配
  • 加载、连接
  • 初始化
  • 执行方法

Java代码是如何在JVM中运行的
https://kuberxy.github.io/2020/09/20/Java代码是如何在JVM中运行的/
作者
Mr.x
发布于
2020年9月20日
许可协议