有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

有效的Java说:

A third common source of memory leaks is listeners and other callbacks. If you implement an API where clients register callbacks but don’t deregister them explicitly, they will accumulate unless you take some action. The best way to ensure that callbacks are garbage collected promptly is to store only weak references to them, for instance, by storing them only as keys in a WeakHashMap.

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


共 (3) 个答案

  1. # 2 楼答案

    用一个快速(粗略)的例子来说明这个概念,考虑如下:

    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);
        }
    
        ...
    }
    

    如果客户端类随后使用这个FileMonitorAPI,它们可能会这样做:

    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被销毁或应用程序退出

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

    可以用^{}替换FileMonitor中的HashSet,并将处理程序用作键,因为当对对象的所有其他引用都消失时,后者将自动从集合中删除处理程序

  2. # 3 楼答案

    阅读this文章

    关键的收获是:

    You can think of direct references as strong references that require no extra coding to create or access the object. The remaining three types of references are subclasses of the Reference class found in the java.lang.ref package. Soft references are provided by the SoftReference class, weak references by the WeakReference class, and phantom references by PhantomReference.

    Soft references act like a data cache. When system memory is low, the garbage collector can arbitrarily free an object whose only reference is a soft reference. In other words, if there are no strong references to an object, that object is a candidate for release. The garbage collector is required to release any soft references before throwing an OutOfMemoryException.

    Weak references are weaker than soft references. If the only references to an object are weak references, the garbage collector can reclaim the memory used by an object at any time. There is no requirement for a low memory situation. Typically, memory used by the object is reclaimed in the next pass of the garbage collector.

    Phantom references relate to cleanup tasks. They offer a notification immediately before the garbage collector performs the finalization process and frees an object. Consider it a way to do cleanup tasks within an object.

    接下来是WeakListModel列表,我将不发布该列表,以避免混淆此响应