Top Description Inners Fields Constructors Methods
com.google.common.base

public Class FinalizableReferenceQueue

extends Object
implements Closeable
Class Inheritance
All Implemented Interfaces
java.io.Closeable, java.lang.AutoCloseable
Annotations
@J2ktIncompatible
@GwtIncompatible
@ElementTypesAreNonnullByDefault
Imports
com.google.common.annotations.GwtIncompatible, .J2ktIncompatible, .VisibleForTesting, java.io.Closeable, .FileNotFoundException, .IOException, java.lang.ref.PhantomReference, .Reference, .ReferenceQueue, java.lang.reflect.Method, java.net.URL, .URLClassLoader, java.util.logging.Level, .Logger, javax.annotation.CheckForNull

A reference queue with an associated background thread that dequeues references and invokes FinalizableReference#finalizeReferent() on them.

Keep a strong reference to this object until all of the associated referents have been finalized. If this object is garbage collected earlier, the backing thread will not invoke finalizeReferent() on the remaining references.

As an example of how this is used, imagine you have a class MyServer that creates a ServerSocket, and you would like to ensure that the ServerSocket is closed even if the MyServer object is garbage-collected without calling its close method. You could use a finalizer to accomplish this, but that has a number of well-known problems. Here is how you might use this class instead:

public class MyServer implements Closeable {
  private static final FinalizableReferenceQueue frq = new FinalizableReferenceQueue();
  // You might also share this between several objects.

  private static final Set<Reference<?>> references = Sets.newConcurrentHashSet();
  // This ensures that the FinalizablePhantomReference itself is not garbage-collected.

  private final ServerSocket serverSocket;

  private MyServer(...) {
    ...
    this.serverSocket = new ServerSocket(...);
    ...
  }

  public static MyServer create(...) {
    MyServer myServer = new MyServer(...);
    final ServerSocket serverSocket = myServer.serverSocket;
    Reference<?> reference = new FinalizablePhantomReference<MyServer>(myServer, frq) {
      public void finalizeReferent() {
        references.remove(this):
        if (!serverSocket.isClosed()) {
          ...log a message about how nobody called close()...
          try {
            serverSocket.close();
          } catch (IOException e) {
            ...
          }
        }
      }
    };
    references.add(reference);
    return myServer;
  }

  public void close() {
    serverSocket.close();
  }
}
Author
Bob Lee
Since
2.0

Nested and Inner Type Summary

Modifier and TypeClass and Description
pack-priv static class
FinalizableReferenceQueue.DecoupledLoader

Try to load Finalizer in its own class loader.

pack-priv static class
FinalizableReferenceQueue.DirectLoader

Loads Finalizer directly using the current class loader.

pack-priv static interface
pack-priv static class
FinalizableReferenceQueue.SystemLoader

Tries to load Finalizer from the system class loader.

Field Summary

Modifier and TypeField and Description
private static final String
pack-priv final PhantomReference<Object>
private static final Logger
pack-priv final ReferenceQueue<Object>
queue

The actual reference queue that our background thread will poll.

private static final Method
startFinalizer

Reference to Finalizer.startFinalizer().

pack-priv final boolean
threadStarted

Whether or not the background thread started successfully.

Constructor Summary

AccessConstructor and Description
public
FinalizableReferenceQueue()

Constructs a new queue.

Method Summary

Modifier and TypeMethod and Description
pack-priv void
cleanUp()

Repeatedly dequeues references from the queue and invokes FinalizableReference#finalizeReferent() on them until the queue is empty.

public void
close()

Implements java.io.Closeable.close.

Closes this stream and releases any system resources associated with it.
pack-priv static Method
getStartFinalizer(Class<?> finalizer)

Looks up Finalizer.startFinalizer().

private static Class<?>

Returns:

Finalizer.class
loadFinalizer
(FinalizableReferenceQueue.FinalizerLoader... loaders)

Iterates through the given loaders until it finds one that can load Finalizer.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

FINALIZER_CLASS_NAMEback to summary
private static final String FINALIZER_CLASS_NAME
frqRefback to summary
pack-priv final PhantomReference<Object> frqRef
loggerback to summary
private static final Logger logger
queueback to summary
pack-priv final ReferenceQueue<Object> queue

The actual reference queue that our background thread will poll.

startFinalizerback to summary
private static final Method startFinalizer

Reference to Finalizer.startFinalizer().

threadStartedback to summary
pack-priv final boolean threadStarted

Whether or not the background thread started successfully.

Constructor Detail

FinalizableReferenceQueueback to summary
public FinalizableReferenceQueue()

Constructs a new queue.

Method Detail

cleanUpback to summary
pack-priv void cleanUp()

Repeatedly dequeues references from the queue and invokes FinalizableReference#finalizeReferent() on them until the queue is empty. This method is a no-op if the background thread was created successfully.

closeback to summary
public void close()

Implements java.io.Closeable.close.

Doc from java.io.Closeable.close.

Closes this stream and releases any system resources associated with it. If the stream is already closed then invoking this method has no effect.

As noted in AutoCloseable#close(), cases where the close may fail require careful attention. It is strongly advised to relinquish the underlying resources and to internally mark the Closeable as closed, prior to throwing the IOException.

Annotations
@Override
getStartFinalizerback to summary
pack-priv static Method getStartFinalizer(Class<?> finalizer)

Looks up Finalizer.startFinalizer().

loadFinalizerback to summary
private static Class<?> loadFinalizer(FinalizableReferenceQueue.FinalizerLoader... loaders)

Iterates through the given loaders until it finds one that can load Finalizer.

Returns:Class<?>

Finalizer.class

com.google.common.base back to summary

pack-priv Class FinalizableReferenceQueue.DecoupledLoader

extends Object
implements FinalizerLoader
Class Inheritance
  • java.lang.Object
  • com.google.common.base.FinalizableReferenceQueue.DecoupledLoader
All Implemented Interfaces
com.google.common.base.FinalizableReferenceQueue.FinalizerLoader

Try to load Finalizer in its own class loader. If Finalizer's thread had a direct reference to our class loader (which could be that of a dynamically loaded web application or OSGi bundle), it would prevent our class loader from getting garbage collected.

Field Summary

Modifier and TypeField and Description
private static final String

Constructor Summary

AccessConstructor and Description
pack-priv

Method Summary

Modifier and TypeMethod and Description
pack-priv URL
getBaseUrl()

Gets URL for base of path containing Finalizer.class.

public Class<?>
loadFinalizer()

Implements com.google.common.base.FinalizableReferenceQueue.FinalizerLoader.loadFinalizer.

Returns Finalizer.class or null if this loader shouldn't or can't load it.
pack-priv URLClassLoader
newLoader(URL base)

Creates a class loader with the given base URL as its classpath.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

LOADING_ERRORback to summary
private static final String LOADING_ERROR

Constructor Detail

DecoupledLoaderback to summary
pack-priv DecoupledLoader()

Method Detail

getBaseUrlback to summary
pack-priv URL getBaseUrl() throws IOException

Gets URL for base of path containing Finalizer.class.

loadFinalizerback to summary
public Class<?> loadFinalizer()

Implements com.google.common.base.FinalizableReferenceQueue.FinalizerLoader.loadFinalizer.

Doc from com.google.common.base.FinalizableReferenceQueue.FinalizerLoader.loadFinalizer.

Returns Finalizer.class or null if this loader shouldn't or can't load it.

Annotations
@Override
@CheckForNull
newLoaderback to summary
pack-priv URLClassLoader newLoader(URL base)

Creates a class loader with the given base URL as its classpath.

com.google.common.base back to summary

pack-priv Class FinalizableReferenceQueue.DirectLoader

extends Object
implements FinalizerLoader
Class Inheritance
  • java.lang.Object
  • com.google.common.base.FinalizableReferenceQueue.DirectLoader
All Implemented Interfaces
com.google.common.base.FinalizableReferenceQueue.FinalizerLoader

Loads Finalizer directly using the current class loader. We won't be able to garbage collect this class loader, but at least the world doesn't end.

Constructor Summary

AccessConstructor and Description
pack-priv

Method Summary

Modifier and TypeMethod and Description
public Class<?>
loadFinalizer()

Implements com.google.common.base.FinalizableReferenceQueue.FinalizerLoader.loadFinalizer.

Returns Finalizer.class or null if this loader shouldn't or can't load it.
Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Constructor Detail

DirectLoaderback to summary
pack-priv DirectLoader()

Method Detail

loadFinalizerback to summary
public Class<?> loadFinalizer()

Implements com.google.common.base.FinalizableReferenceQueue.FinalizerLoader.loadFinalizer.

Doc from com.google.common.base.FinalizableReferenceQueue.FinalizerLoader.loadFinalizer.

Returns Finalizer.class or null if this loader shouldn't or can't load it.

Annotations
@Override
com.google.common.base back to summary

pack-priv Interface FinalizableReferenceQueue.FinalizerLoader

Known Direct Implementers
com.google.common.base.FinalizableReferenceQueue.SystemLoader, com.google.common.base.FinalizableReferenceQueue.DecoupledLoader, com.google.common.base.FinalizableReferenceQueue.DirectLoader

Loads Finalizer.class.

Method Summary

Modifier and TypeMethod and Description
public Class<?>
loadFinalizer()

Returns Finalizer.class or null if this loader shouldn't or can't load it.

Method Detail

loadFinalizerback to summary
public Class<?> loadFinalizer()

Returns Finalizer.class or null if this loader shouldn't or can't load it.

Annotations
@CheckForNull
Exceptions
SecurityException:
if we don't have the appropriate privileges
com.google.common.base back to summary

pack-priv Class FinalizableReferenceQueue.SystemLoader

extends Object
implements FinalizerLoader
Class Inheritance
  • java.lang.Object
  • com.google.common.base.FinalizableReferenceQueue.SystemLoader
All Implemented Interfaces
com.google.common.base.FinalizableReferenceQueue.FinalizerLoader

Tries to load Finalizer from the system class loader. If Finalizer is in the system class path, we needn't create a separate loader.

Field Summary

Modifier and TypeField and Description
pack-priv static boolean

Constructor Summary

AccessConstructor and Description
pack-priv

Method Summary

Modifier and TypeMethod and Description
public Class<?>
loadFinalizer()

Implements com.google.common.base.FinalizableReferenceQueue.FinalizerLoader.loadFinalizer.

Returns Finalizer.class or null if this loader shouldn't or can't load it.
Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

disabledback to summary
pack-priv static boolean disabled
Annotations
@VisibleForTesting

Constructor Detail

SystemLoaderback to summary
pack-priv SystemLoader()

Method Detail

loadFinalizerback to summary
public Class<?> loadFinalizer()

Implements com.google.common.base.FinalizableReferenceQueue.FinalizerLoader.loadFinalizer.

Doc from com.google.common.base.FinalizableReferenceQueue.FinalizerLoader.loadFinalizer.

Returns Finalizer.class or null if this loader shouldn't or can't load it.

Annotations
@Override
@CheckForNull