2011-06-22 280 views
7

我想知道如何垃圾收集工作時,你有一個類與反射用於獲取一些字段值。 JVM如何意識到這些字段引用的值是可訪問的,因此當前不使用正式語言語法訪問垃圾回收時不適合進行垃圾回收?垃圾收集和反射

一個小片段顯示問題(雖然反射一直過分強調這裏):

/** 
* 
*/ 

import java.lang.reflect.Field; 

public class B { 
    protected B previous = null, next = null; 

    /** 
    * 
    */ 
    public B(B from) { 
     this.previous = from; 
    } 

    public void transition(B to) { 
     this.next = to; 
    } 

    public B next() { 
     try { 
      Field f = getClass().getField("next"); 
      f.setAccessible(true); 
      try { 
       return (B)f.get(this); 
      } finally { 
       f.setAccessible(false); 
      } 
     } catch (Exception e) { 
      throw new IllegalStateException(e); 
     } 
    } 

    public B previous() { 
     try { 
      Field f = getClass().getField("previous"); 
      f.setAccessible(true); 
      try { 
       return (B)f.get(this); 
      } finally { 
       f.setAccessible(false); 
      } 
     } catch (Exception e) { 
      throw new IllegalStateException(e); 
     } 
    } 
} 

乾杯,
克里斯

+0

有趣的問題。它是否受某種嵌入式Java應用程序的啓發? –

+0

你能否給我們一個代碼片段來澄清你的意思:「一個帶反射的類用於獲取一些字段值?」 –

+0

實際上,我正在進行網絡框架的測試,並且有些字段是通過反射來訪問的。想知道反射如何影響內存使用,也許JVM保留對象是不確定的。 –

回答

10

如果您正在訪問一個實例的領域,那麼你會仍然需要參考該實例。對於那種情況,GC沒有任何異常。

+0

謝謝,這很有道理:) –

5

要訪問對象的字段,您必須具有對該對象的引用。如果您通過反射或直接訪問它,對於是否有強烈的對象引用沒有任何影響。

1

這是一個奇怪的測試案例:你使用反射來訪問「this」。根據定義,「this」在聲明類的實例方法中使用時是活的,因此不會被GCed。

但更重要的一點是,反射只是允許你在已經有引用的對象中操作字段等。這是關鍵 - 如果您可以反映實例進行檢查,您顯然仍然有一個對象的參考,因此它保持活着。