Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如果某个活动具有在别处引用的静态成员变量,则该活动是否可以被垃圾回收?_Java_Android_Android Activity_Garbage Collection_Static Members - Fatal编程技术网

Java 如果某个活动具有在别处引用的静态成员变量,则该活动是否可以被垃圾回收?

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

假设一个活动A有一些静态成员变量,因为当VM第一次加载类时,静态被加载到内存中并保持不变,所以我想知道如果其他类B持有类A的任何静态变量,活动在垃圾收集方面会发生什么。? 不收吗??
是否将它收集并将静态初始化为初始值?

您不能保留对类的静态变量(或任何变量)的引用

只能保存对对象的引用,而不能保存变量本身

例如


在这种情况下,只有
新对象()
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;