首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何避免回调中的内存泄漏?

如何避免回调中的内存泄漏?
EN

Stack Overflow用户
提问于 2010-05-19 01:14:19
回答 3查看 7.7K关注 0票数 23

Effective Java说:

内存泄漏的第三个常见来源是侦听器和其他回调。如果您实现了一个API,其中客户端注册了回调,但没有显式地注销它们,那么这些回调将会累积,除非您采取一些措施。确保回调被及时垃圾回收的最好方法是只存储对它们的弱引用,例如,将它们仅作为键存储在WeakHashMap中。

我是爪哇的初学者。谁能教我如何在回调中创建弱引用,并告诉我它们如何解决内存泄漏问题?谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-05-19 01:19:47

阅读this文章

关键的收获是:

您可以将直接引用视为强引用,无需额外编码即可创建或访问对象。其余三种类型的引用是在java.lang.ref包中找到的Reference类的子类。软引用由SoftReference类提供,弱引用由WeakReference类提供,幻影引用由PhantomReference提供。

软引用的作用类似于数据缓存。当系统内存不足时,垃圾回收器可以任意释放唯一引用是软引用的对象。换句话说,如果没有对对象的强引用,则该对象是发布的候选对象。在抛出OutOfMemoryException之前,垃圾收集器需要释放任何软引用。

弱引用比软引用弱。如果对对象的唯一引用是弱引用,垃圾回收器可以随时回收对象使用的内存。对于内存不足的情况没有要求。通常,对象使用的内存在垃圾回收器的下一次传递中被回收。

虚拟引用与清理任务相关。它们在垃圾收集器执行终结化过程并释放对象之前立即提供通知。将其视为在对象中执行清理任务的一种方式。

然后是WeakListModel清单,我不会张贴它,以免弄乱这个响应。

票数 13
EN

Stack Overflow用户

发布于 2011-12-12 22:14:04

为了用一个简单的例子来说明这个概念,请考虑以下内容:

代码语言:javascript
复制
public interface ChangeHandler {
    public void handleChange();
}

public class FileMonitor {

    private File file;
    private Set<ChangeHandler> handlers = new HashSet<ChangeHandler>();

    public FileMonitor(File file) { 
        this.file = file;
    }

    public void registerChangeHandler(ChangeHandler handler) {
        this.handlers.add(handler);
    } 

    public void unregisterChangeHandler(ChangeHandler handler) {
        this.handlers.remove(handler);
    }

    ...
}

如果客户端类随后使用此FileMonitor应用程序接口,则它们可能会这样做:

代码语言:javascript
复制
public class MyClass {

    File myFile = new File(...);
    FileMonitor monitor = new FileMonitor(myFile);

    public void something() {
        ...
        ChangeHandler myHandler = getChangeHandler();
        monitor.registerChangeHandler(myHandler);
        ...
    }
}

如果MyClass的作者在处理完处理程序后忘记调用unregisterChangeHandler(),则FileMonitorHashSet将永远引用已注册的实例,导致它一直保留在内存中,直到FileMonitor被销毁或应用程序退出。

为了防止这种情况,布洛赫建议使用弱引用集合而不是HashSet,这样如果您的MyClass实例被销毁,该引用将从监视器的集合中删除。

您可以将FileMonitor中的HashSet替换为WeakHashMap,并使用处理程序作为键,因为当对该对象的所有其他引用都消失时,处理程序将自动从集合中删除。

票数 9
EN

Stack Overflow用户

发布于 2016-07-22 19:43:44

你也可以在这里找到一个清晰的practical 解释Memory leaks in Android — identify, treat and avoid

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2859464

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档