我在这些场合进行了一些搜索,找不到满意的答案,所以我在这里。 注意:这将是示例代码,因为由于原始代码已被分类,因此我无法发布任何内容。
假设这种情况:
public class Instance
{
private ClassMember classMember = new ClassMember();
// Imagine this method is called once as like the main method of apps.
public static void main(String[] args)
{
new Instance().myMethod();
}
private void myMethod()
{
final SomeObject object = new SomeObject();
// This is the class member that is declared at top of the class.
classMember.addCallback(new Callback()
{
@Override
public void onCall(boolean result)
{
object.setResult(result).report(); // I'm done with this object, want to release it.
// After this call, will there be a leak due to "SomeObject object"?
// If so, how can this be prevented from happening?
}
});
object.makeCall(classMember); // asynchronous task such as Internet connections.
}
}
让我们解释变量和类:
现在,我想知道的是,由于“最终SomeObject对象”,可能会发生内存泄漏,我想通过在“ onCall()”方法中收到回调后将其释放(例如将其设置为null)来释放它,以防止它泄漏。但是因为它是最终的,所以我不能这样做,因此我正在寻找替代方法。
有什么建议吗?谢谢。
答案 0 :(得分:1)
鉴于提供的代码,没有someObject
为final
导致的内存泄漏。该实例仅在myMethod
的范围内使用,并且未引用外部(至少在Instance
之外)。也就是说,GC将注意到可以在myMethod
或异步makeCall
完成之后对其进行收集。
我唯一担心的是您提到对makeCall
的调用可能根本无法完成。您必须记住,在调用完成之前,此调用上下文中的所有资源将无法收集。那就是Instance
,ClassMember
和SomeObject
的实例将在makeCall
期间保留在堆上。
当然,如果您在makeCall
中做一些愚蠢的事情,则会以一种或另一种方式泄漏。
更新:
正如@Seelenvirtuose指出的那样,您的示例代码可能有点过分简化,导致做出错误的假设。我的答案是正确的,只要Instance
的实例在提供的代码中的使用方式为一体即可。您必须知道,每次调用myMethod
和每次调用classMember.addCallback
时,classMember
都会引用在object
中创建的myMethod
实例。也就是说,对object
的引用将累积在classMember
中,因此在Instance
的相应实例中-这就是我至少在Instance
< / em>。给定所提供的代码,您可能最终会遇到内存泄漏或没有内存泄漏的情况。这完全取决于您在现实情况中Instance
的使用情况。
答案 1 :(得分:-1)
最终状态不会阻止它进行垃圾收集。如果执行了回调并且对象未保存在classMember中(由于某些处理程序列表或其他某种原因),则引用计数器将减少为0,因此将被垃圾回收(有时)。