First the garbage collector determines that an object is eligible for collection.
If the object requires finalization then it is placed on the finalization queue; it is now alive again because the queue is a root.
Then the finalizer thread runs, marks the object as no longer requiring finalization, and runs the finalizer.
If at the end of the finalizer the object is still dead then when the GC runs again later, it discovers that there is a dead object that does not require finalization, and cleans it up.