I/O Experte

Von Finalizern zu deterministischer Ressourcenbereinigung

Finalisierung durch AutoCloseable ersetzen und Cleaner nur als defensive Rückfallebene verwenden.

✕ Finalization
@Override
protected void finalize() throws Throwable {
    nativeHandle.release();
}
✓ Java 9+
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();
    }
}
Problem mit diesem Code entdeckt? Sag uns Bescheid.
⏱

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.

Alter Ansatz
finalize() überschreiben
Moderner Ansatz
AutoCloseable und Cleaner
Seit JDK
9
Schwierigkeitsgrad
Experte
Von Finalizern zu deterministischer Ressourcenbereinigung
Verfügbar

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.