2014-10-31 76 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实例)具有相同的生命周期