jvm之类程序执行流程

来源:互联网 发布:云计算培训视频 编辑:程序博客网 时间:2024/06/13 02:23
public class User implements UserDetails, Serializable {  String username;  int age;  User (){  }  public void eat(){   System.out.println("吃饭吃饭");  }  public class Test{  public static void main(String[] args) {       User user = new User();       user.name ="小名"       user.age =15;       user.eat();}  }

首先是java源码被编译器编译成.Class文件, OS会创建一个JVM实例(进行必要的初始化工作,比如初始启动类装载器,初始运行时内存数据区等)。Java虚拟机总是开始于一个main()方法,它是程序的起点,他被执行的线程初始化为程序的初始线程。

开始jvm通过类加载器加载test类,以及user类 以及他们的超类、接口等全部信息和每个类里面的方法,字段,类的修饰符、直接常量:字符串等、方法字段类型等符号引用、指向class的引用、指向类加载器的引用、静态变量。并生成一个方法列表用来存储该类型对象可以调用的方法的直接引用。以上的全部信息都是存储在方法区中的
然后在通过user()构造器在堆中生成user的实例对象,Java 程序在运行时创建的所有类型对象和数组都存储在堆中。然后通过 ‘’=‘’讲其引用地址赋值给 user变量,该变量是在栈中的。栈是用于存放方法中的局部变量,操作数以及异常数据等 到此完成了User user = new User(); 。
然后我们来分析 user.name =”小名”:栈中的user变量通过引用地址找到了存在堆中的 user对象实例中的点name,又因为在java中除了基本数据类型外其他所以的都是引用类型,string又是存在在常量池中的即在方法区中,java会先找常量池中有没有该常量如果有则将该值赋给user.name。所以name指向在常量池中的“小名”。到此该语句结束。
user.age =15;。中的age 是属于基本类型,所以15这个值直接在堆中age上复制城。user.eat();的eat()方法jvm会查找方法区中的方法列表中有没有eat方法,如何有JVM会根据根据方法区中的局部变量区和操作数栈的大小来分配一个新的栈帧的内存大小,并堆入Java栈组建一个栈帧,并将该栈帧压入Java栈中,方法执行完毕时,JVM会弹出该栈帧并释放掉。这里比较负责我们就假它的引用地址赋给堆中user对象的eat()。

到此以上代码结束。下面看我画的简要的内存分析图。
这里写图片描述