通过一个代码实例,来说明变量,方法,对象和类之间在jvm所存放的位置。
public class JvmHeapStackDistribute {
public static void main(String[] args) {
Program program = new Program("java");
program.sayHello();
}
}
/**
* 对象是放在heap中的
*/
class Program{
private String name;
public Program(String name) {
this.name = name;
}
public void sayHello(){
System.out.println("hello this is "+ name );
}
}
下面一个一个来说明
Program类
String name
name变量的声明,是存放在stack区域中的。
而name指向的String对象的引用则是在Heap区域中sayHello 方法
sayHello方法是存放在method区域中的
main 方法中的代码
main方法
存放在方法区域中。jvm启动时,加载文件路径,并找到main方法的入口。
Program program = new Program(“java”);
Program的类信息放在method区域中,产生对象的实例存在heap中。
- program.sayHello();
jvm首先找到对象的实例
找到实例后,通过对象中的方法指针指向具体的方法进行调用过程。
jvm执行程序的具体过程
加载过程
- jvm启动后, 会从类路径中找到包含main方法的入口JvmHeapStackDistribute
- 找到JvmHeapStackDistribute后,读取二进制数据和类的信息,放入到method区域中,并开始执行main方法中的程序
Program program = new Program("java");
创建Program对象实例的过程如下
- 在method区域中没有找到Program类信息,会通过类加载器加载指定路径的Program,并将类信息放入到method区域中
- jvm在method区域中找到Program类信息后,会在heap区域中为Program实例对象分配内存,并在Program的实例对象中持有指向method区域中的Program类的内存地址
- jvm实例完成后会在当前线程的stack中的reference建立实际的应用关系,此时program赋值完成
方法调用栈
在jvm中,方法的调用属于线程的行为,即方法调用本身会发生在调用线程的方法调用栈中:线程的方法调用栈(method preference frame):每个方法的调用就是方法调用栈中的一个frame,该frame包含了方法的参数、局部变量、临时数据等。
program.sayHello()