rah*_*008 4 java android garbage-collection static-members android-activity
假设一个活动A有一些静态成员变量,因为当类首次由VM加载并保留在内存时,静态加载到内存中,我想知道如果其他类B持有A类的任何静态变量,那么对于垃圾收集会发生什么. .?它会被收集吗?是否会收集并将静态初始化为初始值?
Oly*_*Oly 10
类用于示例目的
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;
}
Run Code Online (Sandbox Code Playgroud)
Java对象实例的简单模型是一个内存区域,除了每个实例成员的空间(非静态)之外,还包含一些管理信息,包括对其类对象的引用.的类对象(在运行时在存储器中的实体)包含关于类的各种信息,包括(有关这个问题)空间的每个类的静态成员.请注意,其中一些依赖于JVM.
需要注意的关键是静态成员在运行时(而不是在任何实例对象中)存储在类对象中或与类对象一起存储.
在上面的示例类中,Activity运行时的类对象将具有两个变量,一个原始整数变量(primitiveStatic)和一个Object类型(objectStatic)的引用.该类的每个实例都有自己独特的内存区域,只包含对类对象的单个引用.B具有单个对象引用的空间的实例.C具有单个原始整数值的空间的实例.
垃圾收集器可以删除并最终确定有资格收集的内存中的任何对象.这也适用于类对象,但它并不像实例对象那么简单,如果对象没有对它的引用,则该对象是合格的.类对象和静态字段很少有资格,但是在卸载类的情况下,它们是.有关类卸载的更多信息,请参阅此文档.
我相信你想知道的案例包括:
new Activity();
//or
Activity a = new Activity();
a = null;
Run Code Online (Sandbox Code Playgroud)
设置和分配完成后的案例1.
加载类,创建类对象和静态变量,如上所述.如上所述,创建实例.该实例立即有资格进行垃圾回收.收集时,实例将被销毁,删除对类对象的引用.如果它是程序的结尾或在其他某些情况下,类对象也可能是垃圾收集,删除primitiveStatic和objectStatic变量.在这种情况下,new Object()这是由被称为objectStatic目前也已经对它的引用,并且是在正常的方式依次进行垃圾回收.
B b = new B();
b.referenceField = Activity.objectStatic;
Run Code Online (Sandbox Code Playgroud)
设置和分配完成后的案例2.
如上所述,B创建了一个新实例(以及类的类对象B).在Activity类被加载和创建的类对象,如果没有得到它了.的referenceField在b被设置来指代相同的位置objectStatic字段,它在或与所找到的Activity 类对象.如果Activity卸载了类(在某些情况下发生但不常见),则会删除其类对象,如中所述//1.这一次,new Object()仍然有一个参考,在b.referenceField,所以不符合收集资格.我们留下了B类对象和new Object()一个实例,b每个对象都有一个引用.
Activity a = new Activity();
B b = new B();
b.referenceField = a.objectStatic;
a = null;
Run Code Online (Sandbox Code Playgroud)
设置和分配完成后的案例3.
如上所述Activity,加载类,如果尚未创建类对象,则创建类对象.如上所述,创建实例.同为B类.通过查找a类引用并在其中定位,objectStatic可以从中获取静态引用a并将其分配给b.referenceField.这是一个参考值的拷贝赋值,所以之间没有参考b和a或Activity,但b现在包含的参考new Object()所构建的Activity类.a = null表示Activity最初引用的实例a符合垃圾回收条件.它的对Activity类对象的引用被删除.该Activityclass对象可能有资格进行垃圾回收.如果是,则清除它包含的静态字段.将new Object()通过提到objectStatic现在有一个参考,在b,所以没有资格进行垃圾回收.我们留下了这个对象,以及B类对象,b它包含对每个对象的单个引用(与case相同//2)
Activity a = new Activity();
C c = new C();
c.primitiveField = a.primitiveStatic;
a = null;
Run Code Online (Sandbox Code Playgroud)
设置和分配完成后的案例4.
像中一样//3,Activity加载类,如果尚未创建类对象,则创建一个实例,如上所述.同为C类.通过查找a类引用并在那里定位它,静态原语primitiveStatic从中获取a并分配给它c.primitiveField.这是一个简单的副本任务,所以之间没有参考c和a或Activity.a = null表示Activity最初引用的实例a符合垃圾回收条件.它的对Activity类对象的引用被删除.本Activity类对象可能会变得符合垃圾收集.如果是,则清除它包含的静态字段.该new Object()提到了objectStatic现在已经没有引用,所以是符合垃圾回收.我们留下了C实例,c其原始int值为42 primitiveField.
在所有这些情况下,没有任何对象实例被其他具有对其类静态字段引用的对象的引用(甚至类和它的静态值在某些情况下可以被垃圾收集)的垃圾收集所阻止,即使在这些字段值由类"拥有"(例如final,在类中和类中初始化).
需要注意的是,如果objectStatic字段是final,则它所引用的对象几乎永远不会被收集:Activity必须卸载该类才能使其符合收集条件.如果你有许多静态对象引用,这些都不是在程序设置之后使用的,那么这可能是一个问题,因为即使它们没有被使用它们也会留在并填满内存.
| 归档时间: |
|
| 查看次数: |
1264 次 |
| 最近记录: |