Class LeakDetector<T>

Type Parameters:
T - the resource type.
All Implemented Interfaces:
Runnable, LifeCycle

public class LeakDetector<T> extends AbstractLifeCycle implements Runnable
A facility to detect improper usage of resource pools.

Resource pools usually have a method to acquire a pooled resource and a method to released it back to the pool.

To detect if client code acquires a resource but never releases it, the resource pool can be modified to use a LeakDetector. The modified resource pool should call acquired(Object) every time the method to acquire a resource is called, and released(Object) every time the method to release the resource is called. LeakDetector keeps track of these resources and invokes method leaked(org.eclipse.jetty.util.LeakDetector.LeakInfo) when it detects that a resource has been leaked (that is, acquired but never released).

To detect whether client code releases a resource without having acquired it, the resource pool can be modified to check the return value of released(Object): if false, it means that the resource was not acquired.

IMPLEMENTATION NOTES

This class relies on System.identityHashCode(Object) to create a unique id for each resource passed to acquired(Object) and released(Object). System.identityHashCode(Object) does not guarantee that it will not generate the same number for different objects, but in practice the chance of collision is rare.

LeakDetector uses PhantomReferences to detect leaks. PhantomReferences are enqueued in their ReferenceQueue after they have been garbage collected (differently from WeakReferences that are enqueued before). Since the resource is now garbage collected, LeakDetector checks whether it has been released and if not, it reports a leak. Using PhantomReferences is better than overriding Object.finalize() and works also in those cases where Object.finalize() is not overridable.

  • Constructor Details

    • LeakDetector

      public LeakDetector()
  • Method Details

    • acquired

      public boolean acquired(T resource)
      Tracks the resource as been acquired.
      Parameters:
      resource - the resource that has been acquired
      Returns:
      true whether the resource has been acquired normally, false if the resource has detected a leak (meaning that another acquire occurred before a release of the same resource)
      See Also:
    • released

      public boolean released(T resource)
      Tracks the resource as been released.
      Parameters:
      resource - the resource that has been released
      Returns:
      true whether the resource has been released normally (based on a previous acquire). false if the resource has been released without a prior acquire (such as a double release scenario)
      See Also:
    • id

      public String id(T resource)
      Generates a unique ID for the given resource.
      Parameters:
      resource - the resource to generate the unique ID for
      Returns:
      the unique ID of the given resource
    • doStart

      protected void doStart() throws Exception
      Description copied from class: AbstractLifeCycle
      Method to override to start the lifecycle
      Overrides:
      doStart in class AbstractLifeCycle
      Throws:
      AbstractLifeCycle.StopException - If thrown, the lifecycle will immediately be stopped.
      Exception - If there was a problem starting. Will cause a transition to FAILED state
    • doStop

      protected void doStop() throws Exception
      Description copied from class: AbstractLifeCycle
      Method to override to stop the lifecycle
      Overrides:
      doStop in class AbstractLifeCycle
      Throws:
      Exception - If there was a problem stopping. Will cause a transition to FAILED state
    • run

      public void run()
      Specified by:
      run in interface Runnable
    • leaked

      protected void leaked(LeakDetector<T>.LeakInfo leakInfo)
      Callback method invoked by LeakDetector when it detects that a resource has been leaked.
      Parameters:
      leakInfo - the information about the leak