2014-10-31 14 views
0

從天真的角度來看,它看起來像聲明一個局部變量(即,一個方法內的變量)爲「final」可能導致內存泄漏。在局部變量(不是類聲明或類成員)上使用final可能導致內存泄漏?

例如,

public static MyObject create() 
{ 

    final Long time = System.millis(); 
    return new MyObject() 
    { 
      @Override public Long getTime() {return "Time is: " + time ; } 
    } 
} 

顯然,time字段即使create()爲了已經returnt爲getTime()合作,圍繞保持。

好了,現在說我有這個方法

public static int create() 
{ 

    final Long time = System.millis(); 
    System.out.println(time); 
    return 2;  
} 

time沒有任何內部類引用。 該方法返回後對象是否保持在附近? Y

謝謝,

+0

必須保留*值* (如何返回對象的功能)。當你說*變量*或*字段*保持在附近時,你的意思是什麼? – aioobe 2014-10-31 14:28:37

回答

4

您正在返回的對象存儲它必須返回的值。我不會把這稱爲內存泄漏,因爲這是你想要的代碼。內存泄漏是不希望的內存浪費。

如果您使該方法非靜態,內存泄漏的一個更重要的潛在可能性是。在這種情況下,即使您明顯不需要,也會保留外部類的引用,並保留所有數據。

該方法返回後對象是否保留在附近?

該對象可以在傳遞給println()後進行清理。何時/如果清理取決於GC,但這不被視爲內存泄漏。

+0

對,我可以看到。在我給出的例子中,保持'時間'是正確的。但是說我沒有匿名類對象,該變量會保持嗎? – 2014-10-31 14:24:46

+0

@OneTwoThree你可以舉一個具體的例子,因爲一般情況下它會做正確的事情嗎? – 2014-10-31 14:31:24

+1

更新了問題。謝謝 – 2014-10-31 14:36:00

1

在你的情況下,有一個由編譯器創建的匿名類,並且此類引用具有隱式引用Long對象實例(由'time'變量引用的)的Field。

由'time'變量引用的Long對象的內存爲ON Java堆內存。這個Long對象的內存與創建的匿名實例具有相同的生命週期。 SO - 這裏沒有內存泄漏

對於情況2:即使'create'方法已完成,長對象內存也將存在一段時間,因爲此內存在堆上。這個內存不會被破壞,直到下一個垃圾收集器運行------- SO這裏沒有內存泄漏。

注:

我在一般的情況下回答。在現實世界。如果長對象的值從-127到128,則長對象可以爲POOLED。在這種情況下,由變量'time'引用的長對象可能與整個應用程序(JVM實例)具有相同的生命週期