collector - Verbessert die Verwendung von final für Variablen in Java die Garbage Collection?



java 8 garbage collector (10)

Heute haben meine Kollegen und ich eine Diskussion über die Verwendung des final Schlüsselworts in Java, um die Speicherbereinigung zu verbessern.

Zum Beispiel, wenn Sie eine Methode schreiben wie:

public Double doCalc(final Double value)
{
   final Double maxWeight = 1000.0;
   final Double totalWeight = maxWeight * value;
   return totalWeight;  
}

Das Deklarieren der Variablen in der Methode final würde der Speicherbereinigung helfen, den Speicher nach dem Beenden der Methode aus den nicht verwendeten Variablen in der Methode zu bereinigen.

Ist das wahr?

https://ffff65535.com


Alle Methoden und Variablen können standardmäßig in Unterklassen überschrieben werden. Wenn wir die Unterklassen speichern wollen, um die Mitglieder der Oberklasse zu überschreiben, können wir sie mit dem Schlüsselwort final als endgültig deklarieren. Für zB- final int a=10; final void display(){......} Wenn Sie eine Methode final machen, wird sichergestellt, dass die in der Oberklasse definierte Funktionalität niemals geändert wird. In ähnlicher Weise kann der Wert einer endgültigen Variablen niemals geändert werden. Endgültige Variablen verhalten sich wie Klassenvariablen.


Das einzige, was mir einfällt, ist, dass der Compiler die endgültigen Variablen optimieren und sie als Konstanten in den Code einreihen kann, sodass Sie keinen Speicher zugewiesen bekommen.


Einige Punkte zu klären:

  • Die Nulling-Referenz sollte GC nicht helfen. Wenn dies der Fall wäre, würde dies bedeuten, dass Ihre Variablen über dem Gültigkeitsbereich liegen. Eine Ausnahme ist der Fall von Objekt-Vetternwirtschaft.

  • Es gibt noch keine On-Stack-Zuweisung in Java.

  • Wenn Sie eine Variable final deklarieren, können Sie (unter normalen Umständen) dieser Variablen keinen neuen Wert zuweisen. Da das Finale nichts über den Umfang sagt, sagt es nichts über seine Wirkung auf GC aus.


Endgültige Variablen können nach der ersten Zuweisung nicht geändert werden (vom Compiler erzwungen).

Dies ändert nicht das Verhalten der Garbage Collection als solche. Die einzige Sache ist, dass diese Variablen nicht gelöscht werden können, wenn sie nicht mehr benutzt werden (was die Speicherbereinigung in speicherdynamischen Situationen erleichtern kann).

Sie sollten wissen, dass das Finale dem Compiler erlaubt, Annahmen darüber zu treffen, was optimiert werden soll. Inlining-Code und ohne Code, von dem bekannt ist, dass er nicht erreichbar ist.

final boolean debug = false;

......

if (debug) {
  System.out.println("DEBUG INFO!");
}

Der println wird nicht im Byte-Code enthalten sein.


Es scheint eine Menge Antworten zu geben, die Vermutungen weben. Die Wahrheit ist, es gibt keinen endgültigen Modifikator für lokale Variablen auf Bytecodeebene. Die virtuelle Maschine wird niemals wissen, dass Ihre lokalen Variablen als endgültig definiert wurden oder nicht.

Die Antwort auf Ihre Frage ist ein klares Nein.


GC handelt mit nicht erreichbaren Referenzen. Das hat nichts mit "final" zu tun, was lediglich eine Behauptung der einmaligen Zuordnung ist. Ist es möglich, dass einige VM's GC "final" nutzen können? Ich sehe nicht wie oder warum.


Nein, es ist ausdrücklich nicht wahr.

Denken Sie daran, dass final nicht konstant bedeutet, es bedeutet nur, dass Sie die Referenz nicht ändern können.

final MyObject o = new MyObject();
o.setValue("foo"); // Works just fine
o = new MyObject(); // Doesn't work.

Es kann einige kleine Optimierungen geben, die auf dem Wissen beruhen, dass die JVM die Referenz niemals ändern muss (wie beispielsweise keine Überprüfung, ob sie sich geändert hat), aber sie wäre so geringfügig, dass sie sich keine Sorgen machen muss.

Final sollte als nützliche Metadaten für den Entwickler und nicht als Compiler-Optimierung betrachtet werden.


Nun, ich weiß nichts über die Verwendung des "finalen" Modifikators in diesem Fall oder dessen Auswirkung auf den GC.

Aber ich kann Ihnen Folgendes sagen: Wenn Sie Boxed-Werte anstelle von Primitiven verwenden (z. B. Double statt Double), werden diese Objekte dem Heap und nicht dem Stack zugewiesen, und es entsteht unnötiger Müll, den der GC bereinigen muss.

Ich verwende nur Box-Primitive, wenn dies von einer vorhandenen API gefordert wird, oder wenn ich NULL-fähige Primitive benötige.


absolut, solange das Objekt kürzer ist, was einen großen Vorteil der Speicherverwaltung bietet, untersuchten wir kürzlich die Exportfunktionalität mit Instanzvariablen in einem Test und einem anderen Test mit lokaler Variablen auf Methodenebene. Während des Belastungstests gibt JVM beim ersten Test einen Fehlspeicherfehler aus, und JVM wurde angehalten. aber im zweiten Test, erfolgreich in der Lage, den Bericht wegen der besseren Speicherverwaltung zu bekommen.


final bei lokalen Variablen und Parametern macht keinen Unterschied zu den erzeugten Klassendateien und kann daher die Laufzeitleistung nicht beeinflussen. Wenn eine Klasse keine Unterklassen hat, behandelt HotSpot diese Klasse so, als ob sie sowieso endgültig wäre (sie kann später rückgängig gemacht werden, wenn eine Klasse, die diese Annahme bricht, geladen wird). Ich glaube, dass das final methodische Vorgehen dem Unterricht sehr ähnlich ist. final on static field kann erlauben, dass die Variable als "compile-time constant" interpretiert wird und auf dieser Basis von javac optimiert wird. final auf Feldern erlaubt der JVM eine gewisse Freiheit zu ignorieren passiert vor Beziehungen.





final