Java Reference
In-Depth Information
Listing 8.6 Leaky bundle activator
public class Activator implements BundleActivator {
static class Data {
StringBuffer data = new StringBuffer(8 * 1024 * 1024)
}
static final ThreadLocal leak = new ThreadLocal() {
protected Object initialValue() {
return new Data();
};
};
public void start(BundleContext ctx) {
leak.get();
}
public void stop(BundleContext ctx) {}
}
Each leaked ThreadLocal takes up a noticeable 8 MB . Following recommended prac-
tice, the ThreadLocal is a static member of the class. This is safe because the JVM guar-
antees to supply a distinct instance of the data object for each thread accessing the
ThreadLocal . But how does forgetting to remove the ThreadLocal cause a memory
leak? If you read the ThreadLocal Javadoc, you may expect the JVM to clear up stale
references ( http://java.sun.com/javase/6/docs/api/java/lang/ThreadLocal.html ) :
Each thread holds an implicit reference to its copy of a thread-local variable as long as
the thread is alive and the ThreadLocal instance is accessible; after a thread goes away,
all of its copies of thread-local instances are subject to garbage collection (unless other
references to these copies exist).
If the bundle has been updated and the framework refreshed, surely the stale data
object is no longer accessible and should be removed, right? Unfortunately, the Java 5
ThreadLocal implementation has a subtle behavior that causes it to hang on to values
longer than is strictly necessary.
ThreadLocal behavior in Java 5
The Java 5 ThreadLocal implementation only clears stale thread-local map entries
if set() or remove() is called on another ThreadLocal for the same thread . In the
worst case, even this isn't guaranteed to purge all stale thread-local map entries.
As you'll soon see, missing the remove() call in stop() means that the data object is
kept alive indefinitely because you don't use any other ThreadLocal s in the example.
This in turn keeps your class loader alive. Let's see this leak in action:
$ cd chapter08/memory-leaks
$ ant dist
$ java -verbose:gc -jar launcher.jar bundles
Search WWH ::




Custom Search