java - 内部最终对象(Java)上可能存在内存泄漏
问题描述
我对这些场合进行了一些搜索,但找不到令人满意的答案,所以我来了。注意:这将是一个示例代码,因为我不能发布原始代码中的任何内容,因为它是分类的。
假设这个场合:
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.
}
}
让我们解释一下变量和类:
- Instance 是包含 main 方法的所谓主类。考虑从另一个类调用此方法,这是为简单起见而定义的。
- ClassMember 是一个处理互联网连接回调的类。将与SomeObject一起使用。
- SomeObject 是一个对象,必须在方法中作为 final 实例化,才能在“addCallback”方法中使用。“makeCall”方法是异步的,可能完成也可能没有完成,例如建立互联网连接。
现在,我想知道的是,由于“最终的 SomeObject 对象”可能存在内存泄漏,我想通过在“onCall()”方法接收到回调后释放它来防止它,例如将其设置为 null。但因为它是最终的,我不能这样做,因此我正在寻找替代方案。
有什么建议么?谢谢。
解决方案
鉴于提供的代码,没有内存泄漏,因为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
. 鉴于提供的代码,您最终可能会出现内存泄漏。这完全取决于Instance
您在现实世界场景中的使用情况。
推荐阅读
- python - 如何为两个函数交集的区域编写标题?
- javascript - 如何为多个计划呈现 Paypal 订阅的多个按钮?
- php - 优化查找除数平方和为整数的整数功能
- mongodb - MongoDB 查找算法复杂度
- google-apps-script - 谷歌表格使用当前单元格数据和另一个单元格更新当前单元格
- python - 使用下拉和 matplotlib 绘制交互式绘图
- javascript - Jasmine 测试:如何测试 Promise.then() 块?
- javascript - Bootstrap - 滚动间谍响应不起作用
- ios - 更新旧领域对象的属性如果新数组上不存在
- python-2.7 - scapy 嗅探没有捕捉到wireshark 捕捉到的东西