I used Phantom references in a simplistic, very specialised kind of memory profiler to monitor object creation and destruction. I needed them to keep track of destruction. But the approach is out-dated. (It was written in 2004 targeting J2SE 1.4.) Professional profiling tools are much more powerful and reliable and the newer Java 5 features like JMX or agents and JVMTI can be used for that too.
PhantomReferences
(allways used together with the Reference queue) are superior to finalize
which has some problems and should therefore be avoided. Mainly making objects reachable again. This could be avoided with the finalizer guardian idiom (-> read more in 'Effective Java'). So they are also the new finalize.
Further more phantom references
allow you to determine exactly when an object was removed from memory. They
are in fact the only way to determine that. This isn't generally that
useful, but might come in handy in certain very specific circumstances
like manipulating large images: if you know for sure that an image should be
garbage collected, you can wait until it actually is before attempting to
load the next image, and therefore make the dreaded OutOfMemoryError less
likely. (Quoted from enicholas.)
And as psd wrote first, Roedy Green has a good summary of references.