GC Roots的对象,以及对java类中的成员变量,局部变量,静态变量和常量的不同回收时机的解析

1.作为GC Roots的对象有以下几种

  1. 虚拟机栈(栈帧中的局部变量区,也叫局部变量表)中引用的对象。
  2. 方法区中的类静态属性引用的对象。
  3. 方法区中常量引用的对象。
  4. 本地方法栈中JNI(Native)方法引用的对象。

2.成员变量(实例变量)&局部变量&静态变量(类变量)的区别

成员变量(实例变量)&局部变量区别:

  1. 作用域
  • 成员变量:针对整个类有效。
  • 局部变量:只在某个范围内有效。(一般指的就是方法,语句体内)
  1. 存储位置
  • 成员变量:随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中。
  • 局部变量:在方法被调用,或者语句被执行的时候存在,存储在栈内存中(栈帧中的局部变量表)。
    当方法调用完,或者语句结束后,就自动释放。
  1. 初始值
  • 成员变量:有默认初始值。
    注意:赋值的时候不能把声明和赋值分开
    举例:
1
2
3
4
public class demo{
int x ;
x = 1; //这样不行
}
1
2
3
public class demo{
int x = 10; //这样就可以
}

原因是 :成员变量在类的范围内,存在于堆内存中,会有默认的初始值,在声明的同时已经给变量赋值了。再次”赋值“实际是使用了语句,而类体里面只能出现变量和方法,不能出现语句。

  • 局部变量:没有默认初始值,使用前必须赋值。

成员变量(实例变量)&静态变量(类变量)区别:

  1. 调用方式
    静态变量也称为类变量,可以直接通过类名调用。也可以通过对象名调用。
    这个变量属于类。
    成员变量也称为实例变量,只能通过对象名调用。这个变量属于对象。
  2. 存储位置
    静态变量存储在方法区中。
    成员变量存储在堆内存。
  3. 生命周期
    静态变量随着类的加载而存在,随着类的消失而消失。生命周期长。
    成员变量随着对象的创建而存在,随着对象的消失而消失。
  4. 与对象的相关性
    静态变量是所有对象共享的数据。
    成员变量是每个对象所特有的数据。

关于静态变量和常量的详细解析:

参照:从class文件与JVM加载机制理解final、static、static final

不同的回收机制总结

  1. 变量属于类变量(静态变量),那么永远不会被回收,原因是方法区中的类静态属性引用的对象是GC Roots,不会被回收。
  2. 变量属于实例(成员变量,包括final),则实例被回收才会被顺便回收(和实例一起存在堆中,栈帧中的局部变量区(GC Root)中不再引用,就回收)
  3. 变量属于实例的方法(局部变量),那么他是在栈中临时的(栈帧中的局部变量区(GC Root),GC的区域在堆和方法区,而不在栈),随着方法结束了,栈自动释放了,无需回收。
-------------本文结束感谢您的阅读-------------
愿你所有幸运,都不期而遇;愿你所有美好,都如约而至。