一、栈、堆、方法区
1.栈的特点如下:
1. 栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)
2. JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等)
3. 栈属于线程私有,不能实现线程间的共享!
4. 栈的存储特性是“先进后出,后进先出”
5. 栈是由系统自动分配,速度快!栈是一个连续的内存空间!
2.堆的特点如下:
1. 堆用于存储创建好的对象和数组(数组也是对象) 如:new对象的过程
2. JVM只有一个堆,被所有线程共享
3. 堆是一个不连续的内存空间,分配灵活,速度慢!
3.方法区(又叫静态区)特点如下:
1. JVM只有一个方法区,被所有线程共享!
2. 方法区实际也是堆,只是用于存储 类、常量相关的信息!
3. 用来存放程序中永远是不变或唯一的内容。(类信息【Class对象】、静态变量、字符串常量等)
二、关于的JWM执行代码的图解
1.被调用的方法会依次堆栈,执行的时候是从栈顶开始执行,执行完毕该栈块就会被释放掉!即先进后出,后进先出
2.所有的对象都存活于可被垃圾回收的堆上
3.变量存在于哪个空间要看它是哪种变量,实例变量 或 局部变量(栈变量)
对于创建对象与对象引用的理解:创建某个对象时,对象会获取所有实例变量所需要的空间!
关于 构造函数
三、对象的生命周期
1.局部变量 和 实例变量 的存活周期
局部变量只会存活在声名该变量的方法中,并且只有在声名它的方法中执行才能被使用(栈属于线程私有)
public void read(){
int s =42;
//'s'只能用在此方法中,方法结束,s就会被完全消失
}
实例变量的寿命与对象相同。只要对象还活着,实例变量就还活着。
public class Life{
int size;
public void setSize(int s){
size=s;
//'s'会在方法结束时消失,但size在类中到处可见
}
}
2.引用变量 与 对象 之“死”
我们知道引用变量的作用是对对象的引用。类似于存在于堆栈快中的遥控器,远程连接堆中的对象,以达到引用对象的目的。
只要引用变量活着,对象就会继续活在堆上
死因1:引用永久性的离开它的范围
public class StackRef{
public void foof(){
barf();
}
public void barf(){
Duck d = new Duck();
}
}
死因二:引用变为赋值的其他对象上
public class ReRef{
Duck d = new Duck();
public void go(){
d = new Duck();
}
}
死因三:直接将引用定义为null
public class ReRef{
Duck d = new Duck();
public void go (){
d=null;
}
}