前言:java里面看起来简单的一行代码,但java虚拟机实现其实并不是那么简单。比如很简单的一句
String str = "abc" ;就没有我们想像的那么简单。
先上我们一眼就能看懂的代码:
首先我们要明白的是在java虚拟机内存可以分为三部分:
栈内存(stack)、堆内存(heap)、方法区(静态区)。
栈的特点是:1.栈描述的是方法执行的内存模型,每个方法被调用时都会在
栈中创建一个栈帧(保存局部变量,操作数,方法出口等);
2.JVM为每个线程创建一个栈,用于存放该线程执行的方法信息;
3.栈属于线程私有,不能实现线程间的共享!
4.学过数据结构的都知道,栈的存储特性是“先进后出,后进先出”
5.栈是由系统自动分配,是一个连续的内存空间。
堆的特点如下:
1.堆用于存储创建好的对象和数组(数组也是对象)
2.JVM只有一个堆,被所有线程共享
3.堆是一个不连续的内存空间,分配灵活。
方法区(也叫静态区)的特点如下:
1.JVM只有一个方法区,被所有线程共享
2.方法区其实也是堆,只是用来存储常量,类相关的信息
3.用来存放程序中永远不变或唯一的内容。(类信息【class对象】、静态变量、字符串常量等)
稍微总结一下:一些方法内的局部变量保存在栈内存中,创建好的对象保存在堆内存中,类的相关信息、静态变量、常量保存在方法区。
结合以上我们来跟着代码运行一下,看看发生了什么:
运行程序启动JVM,从方法区中找到main方法开始执行。
在栈内存中开辟一个栈帧,保存main函数相关数据(有局部变量stu和c)
第一句:Student stu = new Student();
调用Student类的构造器,会在栈内存中创建new Student()方法的栈帧,对象stu创建完毕后消失。
且new关键字在堆中开辟内存保存初始化的Student()对象,并通过“=”将该对象地址
赋值给栈内存中的变量stu(stu相当于一个指针,指向new创建的对象所在地址)
第二句:stu.name = "xiaoli" ;
通过stu找到对象中的name属性,并指向常量池中的“xiaoli”。
之后的Computer c = new Computer() ;类似,也是先在栈内存中创建栈帧,并在堆中创建对象后消失。知道mian()方法执行完毕,整个程序也就执行完毕。