Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid memory leaks in callback?

Tags:

Effective Java says:

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.

I am a beginner in Java. Could somebody teach me how to create weak references in callbacks and tell me how they solve the memory leak problems? Thanks.

like image 213
unj2 Avatar asked May 18 '10 17:05

unj2


People also ask

How do you avoid memory leaks?

To avoid memory leaks, memory allocated on heap should always be freed when no longer needed.

Which function can be used to avoid a memory leak?

The only way to avoid memory leak is to manually free() all the memory allocated by you in the during the lifetime of your code. You can use tools such as valgrind to check for memory leaks.

What is the main cause of memory leaks?

A memory leak starts when a program requests a chunk of memory from the operating system for itself and its data. As a program operates, it sometimes needs more memory and makes an additional request.


2 Answers

Read this article

The key take aways are :

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.

followed by the WeakListModel listing which I won't post to avoid cluttering this response.

like image 195
Amir Afghani Avatar answered Oct 02 '22 05:10

Amir Afghani


To illustrate the concept with a quick (crude) example, consider the following:

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

If a client class then uses this FileMonitor API, they might do this:

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

If the author of the MyClass then forgets to call unregisterChangeHandler() when it's done with the handler, the FileMonitor's HashSet will forever reference the instance that was registered, causing it to remain in memory until the FileMonitor is destroyed or the application quits.

To prevent this, Bloch is suggesting using a weak-referencing collection instead of the HashSet, so that if your instance of MyClass is destroyed, the reference will be removed from the monitor's collection.

You might replace the HashSet in FileMonitor with a WeakHashMap and use the handlers as the keys, since the latter will automatically remove the handler from the collection when all other references to the object are gone.

like image 28
Rob Hruska Avatar answered Oct 02 '22 05:10

Rob Hruska