Java 如果某个活动具有在别处引用的静态成员变量,则该活动是否可以被垃圾回收?
假设一个活动A有一些静态成员变量,因为当VM第一次加载类时,静态被加载到内存中并保持不变,所以我想知道如果其他类B持有类A的任何静态变量,活动在垃圾收集方面会发生什么。? 不收吗??Java 如果某个活动具有在别处引用的静态成员变量,则该活动是否可以被垃圾回收?,java,android,android-activity,garbage-collection,static-members,Java,Android,Android Activity,Garbage Collection,Static Members,假设一个活动A有一些静态成员变量,因为当VM第一次加载类时,静态被加载到内存中并保持不变,所以我想知道如果其他类B持有类A的任何静态变量,活动在垃圾收集方面会发生什么。? 不收吗?? 是否将它收集并将静态初始化为初始值?您不能保留对类的静态变量(或任何变量)的引用 只能保存对对象的引用,而不能保存变量本身 例如 在这种情况下,只有新对象()被B引用(因此不能被GCed)。不是变量obj(或类MainActivity)本身。例如,类 public class Activity { publ
是否将它收集并将静态初始化为初始值?您不能保留对类的静态变量(或任何变量)的引用 只能保存对对象的引用,而不能保存变量本身 例如
在这种情况下,只有
新对象()
被B
引用(因此不能被GCed)。不是变量obj
(或类MainActivity
)本身。例如,类
public class Activity {
public static int primitiveStatic = 42;
public static Object objectStatic = new Object();
}
public class B {
public Object referenceField = null;
}
public class C {
public int primitiveField = 0;
}
Java对象实例的简单模型是一个内存区域,除了每个实例成员(非静态)的空间外,还包含一些管理信息,包括对其类对象的引用。类对象(运行时内存中的实体)包含关于类的各种信息,包括(与此问题相关)类的每个静态成员的空间。请注意,其中一些依赖于JVM
需要注意的关键是静态成员在运行时存储在类对象中或与类对象一起存储(而不是存储在任何实例对象中)
在上面的示例类中,运行时的活动
类对象将有两个变量,一个基本整数变量(基本静态
)和一个对象
类型的引用(对象静态
)。类的每个实例都有自己独特的内存区域,只包含对类对象的一个引用。B
的实例具有用于单个对象引用的空间。C
的一个实例有空间容纳一个原始整数值
垃圾收集器可以删除并最终确定内存中符合收集条件的任何对象。这也适用于类对象,但它不像实例对象那样简单,在实例对象中,如果没有对对象的引用,则对象是合格的。类对象和静态字段很少是合格的,但在卸载类的情况下,它们是合格的。有关类卸载的更多信息,请参阅
我相信你想知道的案例包括:
案例1
案例1:设置和任务完成后
加载该类,创建类对象和静态变量,如上所述。如上所述,将创建一个实例。该实例立即符合垃圾收集的条件。收集时,实例将被销毁,从而删除对类对象的引用。如果程序结束或在其他特定情况下,类对象也可能被垃圾收集,从而删除primitiveStatic
和objectStatic
变量。在本例中,由objectStatic
引用的newobject()
现在也没有对它的引用,并且反过来可以正常方式进行垃圾收集
案例2
案例2设置和分配完成后
如上所述,将创建一个新的B
实例(以及类B
的类对象)。将加载活动
类,并创建类对象(如果尚未创建)。b
中的referenceField
设置为引用与objectStatic
字段相同的位置,该字段位于活动
类对象中或与之一起。如果卸载了活动
类(在某些情况下发生,但并不常见),则会按照//1
中的说明删除其类对象。这一次,new Object()
在b.referenceField
中仍然有对它的引用,因此不符合收集条件。剩下的是B
类对象和新对象()
以及一个实例B
,每个实例都有一个引用
案例3
案例3设置和分配完成后
如上所述,活动
类已加载,如果尚未加载,则创建类对象。如上所述,将创建一个实例。对于B
类也是如此。通过查找a
的类引用并将其定位在那里,静态引用objectStatic
从a
获得并分配给b.referenceField
。这是引用值的副本赋值,因此b
和a
或Activity
之间没有引用,但是b
现在包含对Activity
类构造的新对象()
的引用a=null
表示最初由a
引用的活动
实例有资格进行垃圾收集。它对活动
类对象的引用被删除。活动
类对象可能符合垃圾收集的条件。如果是,则清除它包含的静态字段。objectStatic
引用的newobject()
现在在b
中有一个引用,因此不符合垃圾收集的条件。我们只剩下这个对象和B
类对象,以及B
,其中包含对每个对象的单个引用(与case//2
相同)
案例4
案例4设置和分配完成后
像在//3
中一样,加载活动
类,如果尚未创建类对象,则创建类对象,并创建实例,如上所述。C
类也是如此。通过查找a
的类引用并将其定位在那里,静态原语原语
public class Activity {
public static int primitiveStatic = 42;
public static Object objectStatic = new Object();
}
public class B {
public Object referenceField = null;
}
public class C {
public int primitiveField = 0;
}
new Activity();
//or
Activity a = new Activity();
a = null;
B b = new B();
b.referenceField = Activity.objectStatic;
Activity a = new Activity();
B b = new B();
b.referenceField = a.objectStatic;
a = null;
Activity a = new Activity();
C c = new C();
c.primitiveField = a.primitiveStatic;
a = null;