GC Roots的对象,以及对java类中的成员变量,局部变量,静态变量和常量的不同回收时机的解析
1.作为GC Roots的对象有以下几种
- 虚拟机栈(栈帧中的局部变量区,也叫局部变量表)中引用的对象。
- 方法区中的类静态属性引用的对象。
- 方法区中常量引用的对象。
- 本地方法栈中JNI(Native)方法引用的对象。
2.成员变量(实例变量)&局部变量&静态变量(类变量)的区别
成员变量(实例变量)&局部变量区别:
- 作用域
- 成员变量:针对整个类有效。
- 局部变量:只在某个范围内有效。(一般指的就是方法,语句体内)
- 存储位置
- 成员变量:随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中。
- 局部变量:在方法被调用,或者语句被执行的时候存在,存储在栈内存中(栈帧中的局部变量表)。
当方法调用完,或者语句结束后,就自动释放。
- 初始值
- 成员变量:有默认初始值。
注意:赋值的时候不能把声明和赋值分开
举例:
public class demo{
int x ;
x = 1; //这样不行
}
public class demo{
int x = 10; //这样就可以
}
原因是 :成员变量在类的范围内,存在于堆内存中,会有默认的初始值,在声明的同时已经给变量赋值了。再次”赋值“实际是使用了语句,而类体里面只能出现变量和方法,不能出现语句。
- 局部变量:没有默认初始值,使用前必须赋值。
成员变量(实例变量)&静态变量(类变量)区别:
- 调用方式
静态变量也称为类变量,可以直接通过类名调用。也可以通过对象名调用。
这个变量属于类。
成员变量也称为实例变量,只能通过对象名调用。这个变量属于对象。 - 存储位置
静态变量存储在方法区中。
成员变量存储在堆内存。 - 生命周期
静态变量随着类的加载而存在,随着类的消失而消失。生命周期长。
成员变量随着对象的创建而存在,随着对象的消失而消失。 - 与对象的相关性
静态变量是所有对象共享的数据。
成员变量是每个对象所特有的数据。
关于静态变量和常量的详细解析:
参照:从class文件与JVM加载机制理解final、static、static final
不同的回收机制总结
- 变量属于类变量(静态变量),那么永远不会被回收,原因是方法区中的类静态属性引用的对象是GC Roots,不会被回收。
- 变量属于实例(成员变量,包括final),则实例被回收才会被顺便回收(和实例一起存在堆中,栈帧中的局部变量区(GC Root)中不再引用,就回收)
- 变量属于实例的方法(局部变量),那么他是在栈中临时的(栈帧中的局部变量区(GC Root),GC的区域在堆和方法区,而不在栈),随着方法结束了,栈自动释放了,无需回收。