Java方法区、堆、栈、本地方法区及新生代、老年代、元空间整合

按照惯例先上思维导图:

在这里插入图片描述

JVM内存示意图

在这里插入图片描述

堆区三个区域示意图

在这里插入图片描述


思维导图上的内容不再赘述,我将通过一个实例来走一遍JVM执行的整个过程
第一个定义一个普通的类

public class ClassTest {// 类的定义会在执行的时候放入方法区
	private static int i;//静态变量会保存在方法区
	private String name;//实例化以后,name引用会保存在栈区,name的实际值在堆区

	public ClassTest(String name) {
		this.name = name;
	}

	public void printName() {
		System.out.println(this.name);
	}

}

再定义一个实现类

public class Demo {
	public static void main(String[] args) {// main 是一个静态方法 ,保存在方法区
		ClassTest ctest1 = new ClassTest("New Object 1");// 在堆中开辟空间存储第一个对象
		ClassTest ctest2 = new ClassTest("New Object 2");// 在堆中开辟空间存储第二个对象
		ctest1.printName();// 根据引用(地址),在堆中找到实例化的对象,然后根据对象指向方法区中的地址来到方法区中进行方法的相关操作,如:栈帧的执行过程
		ctest2.printName();
	}
}

让我们来看一遍执行过程:

预热过程:我们javac了一个Demo.java,这个时候编译器将java文件转为Demo.class,紧接着,我们又执行了java Demo,JVM(Java Virtual Machine)收到了我们的指令,便开始加载字节码文件,并且从中找到了main()方法作为入口

  1. 第一句:ClassTest ctest1 = new ClassTest(“New Object 1”);JVM看了之后说,好办!我这就去方法区找它去。JVM来到了尚在混沌状态的方法区,大喊一声ClassTest方法在哪里。荒凉的方法区并没有一丝回应,但是这并没有能够阻止JVM来生成一个对象,他运用了洪荒之力,将ClassTest类的定义加载到了方法区。
  2. 加载完毕后JVM马不停蹄地到了堆区,为ClassTest开辟了一亩二分地(开辟了空间),为了下次能够找得到这个地方,JVM便把这个地方的地址保存到了ctest1中,ctest1称为这片空间的引用,引用类似于C/C++中的指针。
  3. 方法区中每个方法会以栈帧的形式存储,栈中的内容为:栈(Frame)是用来存储数据和部分过程结果的数据结构,同时也被用来处理动态链接(Dynamic Linking)、方法返回值和异常分派(Dispatch Exception)。其中包含局部变量表、操作数栈、动态连接表、返回值
  4. 然后呢,咱们看看ctest1.printName(),ctest1(引用)从堆区找到ClassTest实例化的内存空间,然后从堆中找到方法的在方法区中的地址,再方法区中执行方法。
参考

https://my.oschina.net/wangsifangyuan/blog/711329
https://www.cnblogs.com/ygj0930/p/6522828.html
https://blog.csdn.net/flamezyg/article/details/44673951
http://www.cnblogs.com/noKing/p/8167700.html
https://www.cnblogs.com/minisculestep/articles/4934947.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值