Die Zeichenfolge nimmt in jeder Anwendung eine große Menge Speicher ein. Insbesondere das char [] -Array, das den unabhängigen UTF-16-Charakter enthält, trägt am meisten zum Verbrauch von JVM-Speicher bei, weil jedes Zeichen 2 Ziffern einnimmt.
30%des Speichers sind eigentlich sehr häufig, weil die Zeichenfolge für uns das beste Format ist, sondern auch, weil die beliebte HTTP -API eine große Anzahl von String verwendet. Mit dem Java 8 -Update 20 können wir uns nun an eine neue Funktion kontaktieren, die als String bezeichnet wird, um schwer zu werden.
Die Zeichenfolge wird wiederverwendet, um den Innenbereich der Zeichenfolge zu verwenden, das tatsächlich das Char -Array ist, und das Merkmal der Finale, sodass JVM sie willkürlich manipulieren kann.
Der Entwickler berücksichtigt viele Strategien für die Zeichenfolge, aber die endgültige Implementierung wird in der endgültigen Implementierung verwendet:
Immer wenn das Müllwiederherstellungsgerät auf das String -Objekt zugreift, markiert es das Zeichen -Array. Es erhielt den Hash -Wert des Char -Arrays und bestand es mit einem schwachen Hinweis auf das Array. Solange der Müllrecyrior eine andere Zeichenfolge findet und diese Zeichenfolge und das Zeichenarray den gleichen Hash -Code haben, werden die beiden mit einem Zeichen und einem Zeichen verglichen.
Wenn sie nur übereinstimmen, wird eine Zeichenfolge geändert, wodurch auf das Zeichen -Array der zweiten Zeichenfolge hingewiesen wird. Das erste Char -Array wird nicht mehr zitiert, sodass es recycelt werden kann.
Natürlich bringt dieser gesamte Prozess einige Ausgaben mit sich, wird jedoch durch eine sehr enge Obergrenze gesteuert. Wenn sich beispielsweise nicht wiederholt, dass ein Charakter wiederholt wird, wird er für einen bestimmten Zeitraum nicht mehr überprüft.
Wie funktioniert diese Funktion? Zuerst müssen Sie einfach das Java 8 -Update 20 veröffentlichen und dann dieser Konfiguration befolgen: -xmx256m -xx:+useG1GC, um den folgenden Code auszuführen:
Public class lotofstrings {private statische linde linkedList <string> lose_of_strings = new LinkedList <() (); J = 0; );}}}
Dieser Code wird nach 30 Iterationen als outofMemoryError gemeldet.
Öffnen Sie nun die Zeichenfolge, um schwer zu werden. Verwenden Sie die folgende Konfiguration, um den obigen Code auszuführen:
-Xmx256m -xx:+useg1gc -xx:+useScringdgedUplication -xx:+printStringuplicationStator
Zu diesem Zeitpunkt kann es länger laufen und endet erst nach 50 Iterationen.
JVM hat auch gedruckt, was es getan hat, lasst uns einen Blick darauf werfen:
[GC Concurrent STRING-DEDUPLIKATION, 4658,2K-> 0,0B (4658,2K), AVG 99,6%, 0,0165023 Sek.] [Letzter Exec: 0,0165023 Sek. [Skippd: 0 (0,0%)] [Hashed: 119538 (100,0%)] [Bekannt: 0 (0,0%)] [Neu: 119538 (100,0%) 4658,2K] [Deduplicated: 119538 (100,0%) 4658,2K (100,0,0 K. .0.0 ] [Young: 372 (0.3%) 14.5K (0.3%)] [OLD: 119166 (99.7%) 4643.8K (99.7%)] [Total Exec: 4/0.0802259 SECS, IDLE: 4/0.6491928 SECS, BLOCKED : 0/0,0000000 Sekunden] [inspiziert: 557503] [übersprungen: 0 (0,0%)] [Hashed: 556191 (99,8%)] [bekannt: 903 (0,2%)] [neu: 556600 (99,8%) 21,2 m] [ Dedupliziert: 554727 (99,7%) 21,1 m (99,6%)] [jung: 1101 (0,2%) 43,0 K (0,2%)] [alt: 553626 (99,8%) 21,1 m (99,8%)] [Tabelle] [Tabelle] [Speicherverbrauch : 81.1k] [Größe: 2048, min: 1024, max: 16777216] [Einträge: 2776, Ladung: 135,5%, zwischengespeichert: 0, hinzugefügt: 2776, entfernt: 0] [Größenzahl: 1, Schrumpfung dreifach: 13 65 (65 (66,7%), Wachstumsschwellenwert: 4096 (200,0%)] [Rehash Count: 0, Rehash -Schwellenwert: 120, Hash -Saat: 0x0] [Altersschwelle: 3] [Warteschlange] [fallen: 0]
Aus Gründen der Bequemlichkeit müssen wir nicht die Hinzufügung aller Daten selbst berechnen, und es reicht aus, sie bequem zu verwenden.
Das obige Codesegment sieht vor, dass die Zeichenfolge schwer erreicht ist.
Die oben genannten Funktionen werden gerade gestartet, was bedeutet, dass es möglicherweise nicht umfassend überprüft wird.具体的数据在实际的应用中可能看起来有差别 , 尤其是那些应用中字符串被多次使用和传递 , 因此一些字符串可能被跳过或者早就有了 Hashcode (正如你可能知道的那样 , , Ein String -Hash -Code wurde faul geladen).
In den obigen Fällen ist die gesamte Zeichenfolge schwer und 4,5 MB Daten werden im Speicher entfernt.
[Tabelle] Ein Teil der statistischen Informationen zur internen Tracking -Tabelle ist angegeben.
Was ist der Unterschied zwischen Stringgewichtung und String -Wohnsitz? Tatsächlich hängt die Zeichenfolge davon ab, die der Residenz ähnelt.
Die Kontroverse des Schöpfers des JDK -Verbesserungsvorschlags von 192 ist, dass Entwickler häufig nicht wissen, wo die ansässige Zeichenfolge angemessen ist, oder sie wird durch das Framework versteckt. Von dem Land) benötigen Sie einen gesunden Menschenverstand.
Wenn die Saite im Anwendungs -Thread bleibt, erhöht die Müllrückgewinnung während der Laufzeit die Saiten nicht. Es wird zu viel Druck zu GC hinzufügen, so dass die Zeichenfolge überhaupt nicht auftritt.