JVM运行时数据区域的三大核心:
Heap Area
1.存储的全部都是Object对象实例,对象实例中一般都包含了其数据成员以及与该对象对应的Class的信息。
2.一个JVM实例在运行的时候只有一个Heap区域,该区域被所有的线程共享。
Method Area(静态成员区)
1.包含整个程序的Class、static成员等。
2.被所有的线程共享。
Stack Area
1.Stack是线程私有的,每个线程都会包含一个Stack区,Stack区域含有基本的数据类型,以及对象的引用,其他线程是不能直接访问的。
2.分为三大部分:基本数据类型区、操作指令区、上下文等。
package com.expgiga.Test;
/**
* 当JVM进程启动时,会从类的加载路径中找到包含main方法的入口类HelloJVM
* 找到HelloJVM后,会直接读取该文中的二进制数据,并且把该类的信息放到运行时Method Area。
* 定位到HelloJVM中的main方法字节码并开始执行main方法中的指令。
* 此时,会创建Student实例对象并且使用s来应用该对象(或者说对该对象命名),其原理如下:
* 1.JVM会直接到Method Area中去查找Student类的信息,此时发现没有Student类,通过类加载器加载该Student类文件。
* 2.在JVM的Method Area加载并找到了Student类之后会在Heap Area中为Student实例对象分配内存,并且在Student的实例对象中持有指向
* Method Area中的Student类的应用(内存地址)
* 3.JVM实例化完成后,会在当前线程中为Stack中的reference建立实际的应用关系,此时会赋值给s
*
* 在JVM方法的调用是属于线程的行为,方法调用会发生在调用线程的方法调用栈:
* 线程的方法调用栈,每一个方法的调用就是方法调用栈中的一个Frame,该Frame包含了方法的参数、局部变量、临时数据等
*/
public class HelloJVM {
//在JVM运行的时候会通过反射的方式到Method Area找到入口类的入口方法main()
public static void main(String[] args) { //main()放在Method Area
/*
s是放在主线程的Stack Area中
Student对象实例是放在所有线程共享的Heap Area
*/
Student s = new Student("Zhang San");
//首先会通过s指针(句柄),找Student对象,当找到该对象后,会通过对象内部指向方法区域的指针来调用具体的方法区执行任务
s.sayHello();
}
}
class Student {
private String name; //name作为引用,是放在Stack Area,但是name指向的String对象是放在Heap Area
Student(String name) {
this.name = name;
}
void sayHello() { //sayHell()放在Method Area
System.out.println("Hello, this is " + this.name);
}
}