NytroX hat geschrieben:Und zwar ist afaik RAII nicht orthogonal zum GarbageCollector, weil der GC niemals die Reihenfolge bzw. den Zeitpunkt beim Zerstören.. ääh.. "Finalisieren" der Objekte vorgibt (zumindest in Java und C#, im Gegensatz zu RAII in C/C++). Das führt zwangsweise zu Problemen, die man nur umgehen kann wenn:
- man trotz GC eine Möglichkeit hat, Objekte explizit feizugeben (wie z.B. in D)
Naja, Javas neue verallgemeinerte
close()-Methode tut doch genau das. Wenn du das Objekt danach als zerstört betrachtest, hast du eine explizite Freigabe. Dass das Objekt noch in einer Art Zombiezustand vor sich hin vegetiert, bis der GC es einsammelt, ist nicht schön, aber auch nicht wirklich problematisch. Finalisierung und Freigabe des Speichers sind im Rahmen dieses Mechanismus jedenfalls erstmal irrelevant. Die Reihenfolge wird im Rahmen der try-with-resources-Funktionalität durchaus eingehalten. Der Rest lebt in Java ja eh vollständig in diesem Raum unbestimmter Lebensdauer, so wie es unverwaltete C++-Objekte täten. Aber klar, dass das unschön gegenüber einer strikt geordneten und verwalteten Lebensdauer wie in sauberem und modernem C++ ist, haben wir hier ja schon hinlänglich diskutiert.
NytroX hat geschrieben:- man GC und RAII immer komplett trennt (wie z.B. in ManagedC++)
Hast du gerade Managed C++ gesagt? Falls du C++/CLI meinst, das ist keine Sprache, sondern ein ... Kompatibilitätskonstrukt. ;)
NytroX hat geschrieben:Aber speziell das try-with-resources hat noch ein ganz anderes Problem: man muss genau wissen was man tut.
Code: Alles auswählen
try (BufferedReader br = new MyBufferedReader(
new MyFileReader("C:/temp/file.txt"))) {
System.out.println(br.readLine());
}
kann ein Resource-Leak sein. Und meiner Meinung nach ist das alles andere als offensichtlich.
Ja, das betrachte ich auch mit großer Sorge, zumal dein Beispiel genau so in dem entsprechenden offiziellen Abschnitt zur Einführung der neuen Sprachfeatures anzutreffen ist.
NytroX hat geschrieben:Ich erlebe in der Praxis öfter Probleme, weil sich Java-Programmierer darauf verlassen, dass der GC sowas schon schaukelt. Tut er aber meistens nicht, jedenfalls nicht wenn das Programm mal 3 Tage am Stück performant rennen soll.
Schön, dass auch Praktiker die Probleme des GCs in Realität sehen. :P
NytroX hat geschrieben:Aber inzwischen frage ich mich, ob man überhaupt einen GC braucht.
Genau, ganz sicher nicht! (Noch ein bisschen Chromanoid ärgern.) ;)
NytroX hat geschrieben:Fazit: Sowohl RAII, ReferenceCount als auch der GC sind Konstrukte, mit denen ich mich eigentlich garnicht rumärgern will, und es eigentlich auch nicht müsste.
Ähm ja klar, C-Style alles zu Fuß geht immer, mit all den damit verbundenen Unsicherheiten. Allerdings dann auf keinen Fall mit Exceptions. Und selbst mit Fehlerbehandlung per Rückgabewerte landet man dann wohl schnell wieder beim
goto. Bei RAII geht es doch gerade darum, Ressourcenverwaltung so umzusetzen, dass nichts vergessen werden kann, weil unabhängig von Erfolg oder Fehlschlag immer alles korrekt aufgeräumt und zurückgesetzt wird. Sprich, wenn du dich nicht mit RAII rumärgern willst, dann musst du dich eben mit Ressourcenverwaltung rumärgern.
NytroX hat geschrieben:Achja: und wohin gehören nun Ressourcen wie Dateien oder Socket-Verbindungen ?
Antwort: teils-teils. Man hat einen ResourceManager (der gehört zu a) und eine konkrete Instanz, die man vor der Nutzung vom Manager anfragt und danach wieder abgibt (also b).
Warum auch immer du hier einen Manager brauchst, wenn du eh alles manuell abgibst. Ich bin jedenfalls sehr zufrieden, dass RAII in C++ meinen Code um den Faktor 3 verkürzt, weil sämtliche Fehlerbehandlung und Ressourcenverwaltung automatisiert und wohldefiniert abläuft, ohne dass ich mir darüber je Gedanken machen müsste.
Ich habe in der Vergangenheit leider allzu oft beobachtet, dass Leute, die auf RAII und Ausnahmen zu Gunsten "klassischer" Fehlerbehandlung verzichten, am Ende vor allem auf eins Verzichten, nämlich die Fehlerbehandlung selbst, was ganz sicher nicht richtig ist. ;)