枚举声明声明终结器是编译时错误.枚举类型的实例可能永远不会最终确定.
由于终结器在垃圾收集器运行之前执行,如果终结器不存在,这是否意味着enum类型始终保持在内存中,并且垃圾收集器不适用于enum类型?
Edw*_*rzo 39
如果编译枚举就好
enum Suit {SPADES, HEARTS, CLUBS, DIAMONDS}
Run Code Online (Sandbox Code Playgroud)
您将看到生成的字节码(即javap -p Suit)对应于合成类:
final class Suit extends java.lang.Enum<Suit> {
public static final Suit SPADES;
public static final Suit HEARTS;
public static final Suit CLUBS;
public static final Suit DIAMONDS;
private static final Suit[] $VALUES;
public static Suit[] values();
public static Suit valueOf(java.lang.String);
private Suit();
}
Run Code Online (Sandbox Code Playgroud)
因此,枚举的实例是类本身的静态成员.然后我认为这可能是垃圾收集的唯一方法是,如果类本身是垃圾收集的,如果它是由系统类加载器加载的话,这是不太可能发生的.
Bhe*_*ung 14
垃圾收集器是否在Enum类型上运行?
只是一个实验来证明枚举实例可以符合gc条件.
定义样本枚举如下 -
public enum SampleEnum { ONE; }
Run Code Online (Sandbox Code Playgroud)
和测试代码 -
Class<SampleEnum> clazz = SampleEnum.class;
String[] fieldNames = {
"ONE", "ENUM$VALUES"
};
//create a weak reference to the instance
WeakReference<SampleEnum> ref = new WeakReference<SampleEnum>(SampleEnum.ONE);
//remove the hard references
for (String fieldName: fieldNames) {
Field feld = clazz.getDeclaredField(fieldName);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(feld, feld.getModifiers() & ~Modifier.FINAL);
feld.setAccessible(true);
feld.set(null, null);
}
//wait until a gc occurs and clears the weak ref
while (ref.get() != null) {
System.out.println("Waiting ...");
System.gc();
}
//output just to verify that the weak ref is cleared by the gc
System.out.println("Weak reference is cleared!");
Run Code Online (Sandbox Code Playgroud)
尝试使用该-verbose:gc选项.
由于终结器在垃圾收集器运行之前执行,如果终结器不存在,这是否意味着枚举类型始终保持在内存中,垃圾收集器不适用于枚举类型?
实际上,终结器的存在/不存在与任何对象是否将被gc'ed无关.枚举实例不是gc'ed,因为它们由编译器生成的枚举类中的静态字段引用.
| 归档时间: |
|
| 查看次数: |
3257 次 |
| 最近记录: |