Aus dem Gedächtnis: In Laiens Begriffen bedeutet dies, dass nicht genügend Speicher vorhanden ist. Zum Beispiel wird das ständige Erstellen eines großen Objekts in einer unendlichen Schleife bald einen Speicherüberlauf verursachen.
Leck des Speichers: Bezieht sich auf die rechtzeitige Freisetzung des Speichers nach der Zuweisung von Speicher an ein Objekt, wenn das Objekt nicht mehr verwendet wird, was dazu führt, dass die Speichereinheit besetzt ist und der tatsächliche verfügbare Speicher wie ein Speicherleck reduziert wird.
Speicherleck, das durch Substring -Methode verursacht wird
Substring (int begindex, int endndex) ist eine Methode der String -Klasse, aber diese Methode wird in JDK6 und JDK7 völlig unterschiedlich implementiert (obwohl beide den gleichen Effekt erzielen). Das Verständnis ihrer Implementierungsdetails kann Ihnen helfen, sie besser zu nutzen, da eine unsachgemäße Verwendung von Substring in JDK1.6 zu schwerwiegenden Problemen mit Leckerleitern führen kann.
1. Die Rolle des Substrings
Die Methode Substring (int begindex, int endindex) gibt ein Substring zurück, beginnend mit Beginnindex der übergeordneten Zeichenfolge und endet bei Endindex-1. Der Index der übergeordneten Zeichenfolge beginnt bei 0, und das Substring enthält begindex und nicht endindex
String x = "abcdef"; x = str.substring (1,3); System.out.println (x);
Die Ausgabe des obigen Programms ist "BC"
2. Implementierungsprinzip
Die String -Klasse ist unveränderlich. Wenn X im obigen zweiten Satz neu zugewiesen wird, zeigt es auf ein neues String -Objekt. Es gibt jedoch keine genaue Beschreibung oder repräsentiert die tatsächliche Situation, die im Haufen auftritt. Was beim Substring wirklich passiert, ist der Unterschied zwischen den beiden.
Substring -Implementierung in JDK6
Das String -Objekt wird als Zeichenarray gespeichert. Es gibt 3 Felder in der String -Klasse: char [] Wert, int -offset und int count, die jeweils zum Speichern des realen Zeichenarrays, der Ausgangsposition des Arrays und der Anzahl der Zeichen der Zeichenfolge verwendet werden. Diese 3 Variablen können eine Zeichenfolge bestimmen. Wenn die Substring -Methode aufgerufen wird, wird eine neue Zeichenfolge erstellt, aber der obige Zeichen -Array -Wert verwendet weiterhin den Wert des ursprünglichen übergeordneten Arrays. Der einzige Unterschied zwischen Eltern- und Kinderarray besteht darin, dass die Werte von Anzahl und Offset unterschiedlich sind.
Schauen Sie sich den Quellcode der Substring -Implementierung in JDK6 an:
public String substring (int begindex, int EndIndex) {if (begindex <0) {neue StringIndexoutOfBoundSexception (begindex); } if (EndIndex> count) {throck -stringIndexoutOfBoundSexception (EndIndex); } if (begindeIndex> endindex) {throck neue stringIndexoutofBoundSexception (EndIndex - begindex); } return ((begindex == 0) && (endindex == count))? Dies: New String (Offset + begindex, EndIndex - begindex, Wert); // Es wird verwendet, um denselben Char -Array -Wert wie die übergeordnete Zeichenfolge zu verwenden} String (int offset, int count, char value []) {this.Value = value; this.offset = offset; this.count = count; }String str = "abcdefghijklMnopqrst"; String sub = str.substring (1, 3); str = null;
Dieses einfache Programm verfügt über zwei String -Variablen Str und Sub. Die Unterzeichenfolge wird durch die übergeordnete Zeichenfolge str. Wenn das obige Programm in JDK1.6 ausgeführt wird, wissen wir, dass die Zuordnung des Speicherraums des Arrays auf dem Heap durchgeführt wird, dann ist der interne char -Array -Wert von SUB und Strel dieselbe, dh das obige Zeichen -Array, das aus Zeichen a ~ Zeichen t besteht. Der einzige Unterschied zwischen Str und Sub ist der Unterschied zwischen Beginnindex und Charakterlängenzahl im Array. Im dritten Satz machen wir die STR -Referenz leer, die den von STR besetzten Raum freien soll. Zu diesem Zeitpunkt kann GC dieses große Zeichen -Array jedoch nicht recyceln, da er immer noch in der Sub -String referenziert wird, obwohl Sub nur einen kleinen Teil dieses großen Arrays abfängt. Wenn STR eine sehr große Schnur ist, ist dieser Abfall sehr offensichtlich und kann sogar Leistungsprobleme bewirken. Sie können dieses Problem lösen durch:
Es verwendet die String -Spleißtechnologie, die eine neue Zeichenfolge erstellt. Mit dieser neuen Zeichenfolge wird ein neues internes Char -Array verwendet, um die tatsächlich benötigten Zeichen zu speichern, so dass das Zeichen -Array des übergeordneten Arrays nicht von anderen Quellen verwiesen wird. Sei str = null, und der gesamte von STR besetzte Raum wird im nächsten Mal recycelt, wenn GC recycelt wird. Aber so zu schreiben ist offensichtlich nicht gut aussehend, also wird in JDK7 das Substring neu implementiert.
Substring -Implementierung in JDK7
Verbesserte Implementierung von Substring in JDK7, das tatsächlich ein neues Zeichen -Array im Haufen für abgefangene Substrings für Substrings erzeugt.
Überprüfen Sie den Implementierungsquellcode der Substring -Methode der String -Klasse in JDK7:
public String substring (int begindex, int EndIndex) {if (begindex <0) {neue StringIndexoutOfBoundSexception (begindex); } if (EndIndex> value.length) {neue stringIndexoutOfBoundSexception (EndIndex); } int sublen = endindex - begindex; if (sublen <0) {neue StringIndexoutOfBoundSexception (Sublen); } return ((begindex == 0) && (endindex == value.length))? Dies: neuer String (Wert, begindex, sublen); } public string (char value [], int offset, int count) {if (offset <0) {throcken Sie neue StringIndexoutOfBoundSexception (Offset); } if (count <0) {neue stringIndexoutofBoundSexception (count); } // HINWEIS: Offset oder Count können in der Nähe von -1 >>> 1 liegen. if (offset> value.length - count) {throdere stringIndexoutofBoundSexception (Offset + count); } this.Value = arrays.copyofRange (Wert, Offset, Offset+Count); }Die CopyofRange -Methode der Arrays -Klasse:
public static char [] copyofrange (char [] original, int von, int to) {int newLength = to - von; if (newLength <0) werfen neue illegalArgumentException (von + ">" + bis); char [] copy = new char [newLength]; // Es wird ein neues Zeichen -Array -System erstellt. Rückgabekopie; }Es kann festgestellt werden, dass ein neues Char -Array für das Substring erstellt wird, um die Zeichen im Substring zu speichern. Auf diese Weise besteht keine notwendige Verbindung zwischen der untergeordneten Zeichenfolge und der übergeordneten Zeichenfolge. Wenn die Referenz der übergeordneten Zeichenfolge ungültig ist, recycelt GC den von der übergeordneten Zeichenfolge besetzten Speicherraum rechtzeitig.
Zusammenfassen
Das obige ist die vollständige Erklärung des durch die Substring -Methode in Java verursachten Speicherlecks. Ich hoffe, es wird für alle hilfreich sein. Interessierte Freunde können weiterhin auf andere verwandte Themen auf dieser Website verweisen. Wenn es Mängel gibt, hinterlassen Sie bitte eine Nachricht, um darauf hinzuweisen. Vielen Dank an Freunde für Ihre Unterstützung für diese Seite!