Von Finalizern zu deterministischer Ressourcenbereinigung
Finalisierung durch AutoCloseable ersetzen und Cleaner nur als defensive Rückfallebene verwenden.
@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();
}
}
Deterministisch
Try-with-resources gibt Ressourcen zu einem bekannten Zeitpunkt frei.
Sichererer Lebenszyklus
Vermeidet die Wiederbelebung durch Finalizer und eine unvorhersehbare Reihenfolge.
Defensive Rückfallebene
Cleaner kann nicht freigegebene Ressourcen bereinigen, ohne finalize() zu überschreiben.
Cleaner und die Kennzeichnung von Finalizern als veraltet sind seit JDK 9 verfügbar (September 2017)
Die Finalisierung ist zur Entfernung veraltet und bietet weder eine zeitnahe Bereinigung noch eine zuverlässige Reihenfolge. AutoCloseable implementieren, damit Aufrufer Ressourcen mit try-with-resources deterministisch freigeben können. Bei nicht freigegebenen Ressourcen kann Cleaner als letztes Mittel dieselbe idempotente Bereinigungsaktion aufrufen; diese Aktion darf das registrierte Objekt nicht referenzieren.