Dai finalizer alla pulizia deterministica delle risorse
Sostituisci la finalizzazione con AutoCloseable e usa Cleaner solo come fallback difensivo.
@Override
protected void finalize() throws Throwable {
nativeHandle.release();
}
final class NativeResource implements AutoCloseable {
private static final Cleaner CLEANER = Cleaner.create();
private static final class State implements Runnable {
private final long handle;
State(long handle) {
this.handle = handle;
}
@Override
public void run() {
release(handle);
}
}
private final Cleaner.Cleanable cleanable;
NativeResource(long handle) {
cleanable = CLEANER.register(this, new State(handle));
}
@Override
public void close() {
cleanable.clean();
}
}
Deterministico
Try-with-resources rilascia le risorse in un momento noto.
Ciclo di vita più sicuro
Evita la resurrezione tramite finalizer e un ordine imprevedibile.
Fallback difensivo
Cleaner può recuperare le risorse non chiuse senza sovrascrivere finalize().
Cleaner e deprecazione della finalizzazione disponibili dal JDK 9 (settembre 2017)
La finalizzazione è deprecata e destinata alla rimozione, e non garantisce né una pulizia tempestiva né un ordine affidabile. Implementa AutoCloseable affinché i chiamanti possano rilasciare le risorse in modo deterministico con try-with-resources. Per le risorse non chiuse, Cleaner può invocare come ultima risorsa la stessa azione di pulizia idempotente; tale azione non deve conservare un riferimento all'oggetto registrato.