代码之家  ›  专栏  ›  技术社区  ›  unj2

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

  •  19
  • unj2  · 技术社区  · 15 年前

    有效的Java说:

    第三个常见的内存泄漏源 是听众和其他回电。如果 您实现了一个API,其中客户机 注册回调但不注册 明确取消注册,他们会 除非你拿了一些 行动。确保这一点的最佳方法 回调被垃圾收集 及时是只存弱 例如,对它们的引用 将它们作为密钥存储在 WeakHashMap。

    我是Java初学者。有人能教我如何在回调中创建弱引用并告诉我它们如何解决内存泄漏问题吗?谢谢。

    3 回复  |  直到 9 年前
        1
  •  13
  •   Amir Afghani    10 年前

    this 文章

    关键在于:

    你可以把直接引用看作 不需要的强引用 创建或访问 对象。剩下的三种类型 引用是 在中找到的引用类 java.lang.ref包。软参考文献 由SoftReference提供 类的弱引用 Weakreference类和幻影 通过phantomreference引用。

    软引用就像数据缓存。 当系统内存不足时,垃圾 收集器可以任意释放 对象的唯一引用是软的 参考文献。换句话说,如果有 不是对对象的强引用, 该对象是 释放。垃圾收集器是 需要释放任何软 在引发 内存不足异常。

    弱引用弱于软引用 参考文献。如果只引用 对象是弱引用, 垃圾收集器可以回收 对象在任何时候使用的内存。 没有要求低 记忆情况。通常,内存 对象使用的是在 垃圾收集器的下一个阶段。

    虚引用与清理相关 任务。他们提供通知 就在垃圾堆前 收集器执行终结 处理并释放对象。考虑 它是在 对象。

    接下来是弱模型列表,我不会发布它来避免混淆这个响应。

        2
  •  8
  •   Rob Hruska MegalomanINA    13 年前

    为了用一个快速(粗略)的例子来说明这个概念,请考虑以下几点:

    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 API,他们可能会这样做:

    public class MyClass {
    
        File myFile = new File(...);
        FileMonitor monitor = new FileMonitor(myFile);
    
        public void something() {
            ...
            ChangeHandler myHandler = getChangeHandler();
            monitor.registerChangeHandler(myHandler);
            ...
        }
    }
    

    如果作者 MyClass 然后忘了打电话 unregisterChangeHandler() 当处理程序完成后, 监测程序 HashSet 将永远引用已注册的实例,使其保留在内存中,直到 监测程序 被破坏或应用程序退出。

    为了防止这种情况,Bloch建议使用弱引用集合,而不是 哈希表 如果您的实例 类名 如果被破坏,引用将从监视器的集合中删除。

    您可以替换 哈希表 在里面 监测程序 用一个 WeakHashMap 并将处理程序用作键,因为当对对象的所有其他引用都消失时,后者将自动从集合中移除处理程序。

        3
  •  1
  •   Andrii Kovalchuk    9 年前

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