【java 基础】代码在jvm的内存运行流程分析总结

堆:存储new出来的对象(包括成员变量、数组、方法的地址)

栈:正在调用的方法中的局部变量(包括方法的参数)

方法区/元空间:.class 字节码文件(包括所有方法)



public class StudentTest {
public static void main(String[] args) {

Student zs = new Student();
zs.name = "张三";
zs.age = 24;
zs.className = "jsd2302";
zs.stuId = "001";

}
}

public class Student {
String name;//描述对象的属性
int age;//作用:给成员变量赋初始值
String className;//语法:与类同名,没有返回值类型(连void都没有)
String stuId;//调用: 在创建(new)对象时被调用
Student(){
}
Student(String name,int age){
this.name=name;
this.age=age;
}
Student(String name1,int age1,String className1,String stuId1){
this.name = name1;
this.age = age1;
this.className=className1;
this.stuId=stuId1;
}
void study(){
System.out.println(this.name + "在学习···");
}
void sayHi(){
System.out.println("大家好,我叫"+ this.name + ",今年" + this.age + "岁了,所在班级为: "
+this.className + "学号为: " + this.stuId);
}
void playWith(String anotherName){
System.out.println(this.name + "正在和" + anotherName + " 一起玩···");
}
}

1 .class文件字节码(包括所有方法)加载到方法区
所以StudentTest的类和main()方法被加载到方法区

2 栈内存是程序运行的主要区域,所以main()方法被加载到栈(stack)区域运行

3 main()方法内的第一行代码就是Student zs类的一个引用

4 代码使用到了Student类,所以把Student类及study()方法加载到方法区

5 zs对Student类进行引用,所以在堆(heap)区域new了一个Student对象给zs

6 因为new对象在堆区域,变量zs在栈区域,所以Student在堆内存区域创建后,
把创建的对象地址给了zs,使用的时候再去按照这个地址拿(可以理解为
stack栈内存主要用来运行,所以为了节省stack栈内存的空间,非必要的存储都不放在stack栈区域,
所以这里只保存了地址)

7 对zs引用的这个Student属性成员变量name进行赋值

8 因为Student的属性成员变量都隶属于Student这个类,
Student被new出来的时候,已经在heap堆内存开创了相应的内存空间,
并进行了初始化,String类型的name初始化为null,int类型的age初始化为0,
以备后面时候。

9 那么age的赋值和name的赋值一样,都是相当于一条指令在stack堆内存进行下达,
那么实际处理的过程是在heap堆内存中。

10 所以属性成员变量在heap堆内,改变对应的初始值age=0到 age =25;

11 zs对Student成员方法Study的调用

12 Student类的成员变量和成员方法在heap堆内存的处理方式不同,
  我们可以理解为,方法的级别要比变量的级别高,或者说方法的逻辑空间要大于变量
  不能在heap堆内存直接存储,前面也提到过方法和类是同时被加载到方法区内的,
  所以也注定了方法是不在heap内存空间内的,

13 所以study()方法被加载到方法区以后,会被存储在方法区并有一个属于自己的内存区域,
然后把这个标记的地址放到heap堆内存,使用的时候随时寻址来拿取。

14 调用study()方法通过heap堆内存的地址在方法区内找到方法后被加载到stack栈内存区域去运行

15 因为栈stack内存空间很宝贵,所以study()方法被执行完,被弹栈出去了

16 study()方法执行完后,main()方法也执行完毕了,所以也被弹出stack栈区域了

17 main方法执行完毕后,Student引用对象的使用也宣告结束,那么这个通过地址的引用也就断开连接了,

18 那么一个对象在JVM内存的heap堆内存中不被使用的情况,那么就成为了内存中的垃圾,
  最后被垃圾回收期回收。

 

 

 

 

 

 

 

 

 

 

posted @ 2023-02-21 19:33  -YBP杨社长  阅读(54)  评论(0)    收藏  举报