String Constant Pool in Java
In Java gibt es zwei Formen der Erstellung von Stringobjekten. Eine ist eine wörtliche Form, wie z. B. String str = "Droid"; und das andere ist eine Standardmethode zum Konstruktion von Objekten mit neuem, z. B. String str = new String ("Droid");. Wir verwenden diese beiden Methoden häufig beim Schreiben von Code, insbesondere beim buchstäblichen Verfahren. Diese beiden Implementierungen haben jedoch tatsächlich einige Unterschiede in der Leistung und des Speicherverbrauchs. All dies liegt an der Tatsache, dass der JVM einen speziellen Speicher beibehält, um die wiederholte Erstellung von Stringobjekten zu verringern, die ein String Constant Pool oder ein String -Literalpool ist.
Wie es funktioniert
Wenn ein String -Objekt in der wörtlichen Form im Code erstellt wird, überprüft das JVM zuerst das wörtliche. Wenn ein Verweis auf ein String -Objekt mit demselben Inhalt im String Constant Pool vorliegt, wird die Referenz zurückgegeben. Andernfalls wird das neue String -Objekt erstellt, und dann wird die Referenz in den String Constant Pool und die Referenz zurückgegeben.
Geben Sie ein Beispiel an
Buchstäbliche Schöpfungsform
String str1 = "Droid";
JVM erkennt dieses wörtliche Literal, hier denken wir, dass kein Objekt mit Inhalten droid ist. Das JVM kann das String -Objekt nicht mit Droideninhalt über den String Constant Pool finden, sodass er dieses String -Objekt erstellt und dann die Referenz des Objekts, das Sie gerade erstellt haben, in den String Constant Pool eingeben, und die Verweise auf die Variable Str1 zurückgeben.
Wenn es als nächstes einen Code gibt
String str2 = "Droid";
In ähnlicher Weise muss das JVM dieses wörtliche Wörtel noch erkennen. Durch die Suche nach dem String Constant Pool stellte der JVM fest, dass der Inhalt "Droid" -Schingobjekt besteht, sodass er die Referenz des vorhandenen String -Objekts auf das variable Str2 zurückgibt. Beachten Sie, dass neue String -Objekte hier nicht neu erstellt werden.
Überprüfen Sie, ob Str1 und Str2 auf dasselbe Objekt verweisen, wir können diesen Code verwenden
System.out.println (str1 == str2);
Das Ergebnis ist wahr.
Mit neu erstellen
String str3 = new String ("Droid");
Wenn wir neu verwenden, um String -Objekte zu konstruieren, werden neue String -Objekte erstellt, unabhängig davon, ob Referenzen auf Objekte mit demselben Inhalt im konstanten String -Pool vorhanden sind. Verwenden wir also den folgenden Code, um ihn zu testen.
String str3 = new String ("Droid");
System.out.println (str1 == str3);
Das Ergebnis ist falsch, wie wir denken, was darauf hinweist, dass die beiden Variablen auf verschiedene Objekte hinweisen.
Praktikum
Wenn Sie für das mit einem neue oben erstellte String -Objekt erstellt wurden, können Sie die Praktikummethode verwenden, wenn Sie eine Referenz zum String Constant Pool hinzufügen möchten.
Überprüfen Sie nach dem Aufrufen von Praktikanten zunächst, ob ein Verweis auf das Objekt im Konstantenpool von String -String besteht. Wenn es vorhanden ist, geben Sie diese Referenz auf die Variable zurück, andernfalls wird die Referenz hinzugefügt und in die Variable zurückgegeben.
String str4 = str3.intern ();
System.out.println (str4 == str1);
Das Ausgabeergebnis ist wahr.
Schwierige Probleme
Voraussetzungen?
Die Voraussetzung für die Implementierung von String Constant Pools ist, dass String -Objekte in Java unveränderlich sind, was sicher sicherstellen kann, dass mehrere Variablen dasselbe Objekt teilen. Wenn das String -Objekt in Java variabel ist und ein Referenzvorgang den Wert des Objekts ändert, sind auch andere Variablen betroffen, dies ist offensichtlich unangemessen.
Referenz oder Objekt
Diese Frage ist am häufigsten, wenn ein String Constant Pool in einer Referenz oder einem Objekt gespeichert wird. Der String Constant Pool speichert Objektreferenzen, nicht Objekte. In Java werden Objekte im Heap -Speicher erstellt.
Aktualisierungsüberprüfung, viele erhaltene Kommentare werden auch dieses Problem diskutieren, und ich überprüfe sie einfach. Überprüfen Sie die Umgebung
22: 18: 54-Androidyue ~/Videos $ cat/etc/os-releaseName = fedoraversion = "17 (fleischiges Wunder)" id = fedoraversion_id = 17pretty_name = "Fedora 17 (kräftig Miracle)"ANSI_COLOR="0;34"CPE_NAME="cpe:/o:fedoraproject:fedora:17"22:19:04-androidyue~/Videos$ java -versionjava version "1.7.0_25"OpenJDK Runtime Environment (fedora-2.3.12.1.fc17-x86_64)OpenJDK 64-Bit Server VM (Build 23.7-B01, gemischter Modus)
Überprüfungsidee: Das folgende Java -Programm liest eine Videodatei mit einer Größe von 82 m und führt Praktikanten in Form einer Zeichenfolge aus.
22: 01: 17 -Androidyue ~/Videos $ ll -LH | grep why_to_learn.mp4-rw-rw-r--. 1 Androidyue Androidyue 82m 20. Oktober 2013 Why_to_learn.mp4
Bestätigungscode
import Java.io.bufufferedReader; Import Java.io.FilenotFoundException; Import Java.io.Filereader; Import Java.io.ioException; öffentliche Klassen testmain {private statische String filecontent; public static void main (String [] args) {fileContent = ReadFileToString (args [0]); if (null! = filecontent) {fileContent = fileContent.intern (); System.out.println ("nicht null"); }} private statische String -ReadFileToString (String -Datei) {bufferedReader reader = null; try {reader = new bufferedReader (New FileReader (Datei)); StringBuffer buff = new StringBuffer (); Stringlinie; while ((line = reader.readline ())! = null) {buff.append (line); } return buff.toString (); } catch (FilenotFoundException e) {e.printstacktrace (); } catch (ioException e) {e.printstacktrace (); } endlich {if (null! = reader) {try {reader.close (); } catch (ioException e) {e.printstacktrace (); }}} return null; }}Da der String Constant Pool in der dauerhaften Generation im Heap -Speicher vorhanden ist, ist er vor Java 8 geeignet. Wir überprüfen, indem wir eine dauerhafte Erzeugung eines geringen Wertes festlegen. Wenn das String -Objekt im String Constant Pool existiert, muss ein Java.lang.outofMemoryError -Permgen -Space -Fehler geworfen werden.
Java -xx: permSize = 6m testmain ~/videos/why_to_learn.mp4
Das Ausführen des Proof -Programms wirft OOM nicht aus, aber dies kann nicht beweisen, dass es als Objekt oder Referenz gespeichert wird.
Dies beweist jedoch zumindest, dass das tatsächliche Inhaltsobjekt -Char [] der Zeichenfolge nicht im String Constant Pool gespeichert ist. In diesem Fall ist es nicht so wichtig, dass der String Constant Pool Verweise auf Zeichenfolgenobjekte oder Zeichenfolgenobjekte speichert. Aber Einzelpersonen neigen immer noch dazu, Referenzen zu speichern.
Für und Wider
Der Vorteil des String Constant Pooling besteht darin, die Erstellung von Zeichenfolgen desselben Inhalts zu verringern und Speicherplatz zu speichern.
Wenn Sie die Nachteile sagen müssen, soll die CPU -Rechenzeit für den Austausch von Platz geopfert werden. Die CPU -Berechnungszeit wird hauptsächlich verwendet, um zu ermitteln, ob Referenzen auf Objekte mit demselben Inhalt im Konstantenpool von String -Konstants vorhanden sind. Die interne Implementierung ist jedoch Hashtable, sodass die Berechnungskosten niedrig sind.
GC Recycling?
Bedeutet dies, dass diese Objekte nicht recycelt werden können?
Erstens sind die gemeinsamen Objekte in der Frage im Allgemeinen kleiner. Soweit ich überprüft habe, gab es in früheren Versionen tatsächlich ein solches Problem, aber mit der Einführung schwacher Referenzen sollte dieses Problem derzeit verschwunden sein.
In Bezug auf dieses Problem können Sie mehr über diesen Artikel erfahren. Praktikanten Strings: Java Glossar
Praktikant verwenden?
Die Voraussetzung für die Verwendung von Praktikanten ist, dass Sie wissen, dass Sie es wirklich verwenden müssen. Zum Beispiel haben wir hier eine Aufzeichnung von Millionen, bei denen ein bestimmter Wert des Datensatzes in Kalifornien, USA, um ein Vielfaches liegt. Wir wollen keine Millionen solcher String -Objekte erstellen. Wir können Praktikanten verwenden, um nur eine Kopie im Speicher zu behalten. Eine eingehende Verständnis des Praktikums finden Sie in der eingehenden Analyse des String#-Praktikums.
Gibt es immer Ausnahmen?
Wissen Sie, dass der folgende Code mehrere String -Objekte erstellt und mehrere Referenzen im String Constant Pool speichert?
String test = "a" + "b" + "c";
Die Antwort ist, dass nur ein Objekt erstellt und nur eine Referenz im konstanten Pool gespeichert wird. Wir verwenden Javap Decompilation und schauen Sie sie sich an.
17:02 $ javap -c TestInternedPoolgccompiled von "TestInternedPoolgc.java" öffentliche Klasse TestinternedPoolgc erweitert Java.lang.Object {public TestInternedPoolgc (); Code: 0: ALOAD_0 1: Invokespecial #1; // Methode Java/Lang/Objekt. "<Init>" :() v 4: returnPublic static void main (java.lang.String []) wirft Java.lang.Exception aus; Code: 0: LDC #2; // String ABC 2: Store_1 3: RückgabeHast du es gesehen? Tatsächlich wurden diese drei Literale während der Zusammenstellungsperiode zu einem synthetisiert. Dies ist tatsächlich eine Optimierung, die vermeidet, redundante String -Objekte zu erstellen und keine Probleme mit der Zeichenfolge aufweist. Für Zeichenfolge können Sie Java -Details anzeigen: String -Nähte.
Das obige ist eine Zusammenstellung der Informationen zu String Constant Pools in Java. Wir werden in Zukunft weiterhin relevante Informationen hinzufügen. Vielen Dank für Ihre Unterstützung für diese Seite!