Einer der bedeutendsten Vorteile von Java ist sein Speicherverwaltungsmechanismus. Sie erstellen einfach das Objekt und der Java-Garbage-Collection-Mechanismus weist den Speicher sorgfältig zu und gibt ihn frei. Allerdings ist es nicht so einfach, da in Java-Anwendungen häufig Speicherlecks auftreten.
In diesem Tutorial wird erklärt, was Speicherlecks sind, warum sie auftreten und wie man sie verhindert.
1. Was ist ein Speicherverlust?
Definition von Speicherverlust: Objekte werden von der Anwendung nicht mehr verwendet, aber der Garbage Collector kann sie nicht entfernen, da auf sie verwiesen wird.
Um diese Definition zu verstehen, müssen wir den Zustand von Objekten im Speicher verstehen. Nicht referenzierte Objekte werden vom Garbage Collector recycelt, während referenzierte Objekte nicht recycelt werden. Ein nicht referenziertes Objekt wird nicht verwendet, da keine anderen Objekte darauf verweisen. Nicht verwendete Objekte sind jedoch nicht unbedingt ohne Referenz, einige von ihnen sind es auch. Dies ist die Ursache für den Speicherverlust.
2. Warum kommt es zu einem Speicherverlust?
Sehen wir uns das folgende Beispiel an, um zu sehen, warum Speicherlecks auftreten. Im Beispiel verweist Objekt A auf Objekt B. Der Lebenszyklus von A (t1-t4) ist viel länger als der Lebenszyklus von B (t2-t3). Wenn B nicht mehr in der Anwendung verwendet wird, enthält A weiterhin einen Verweis darauf. Auf diese Weise kann der Garbage Collector B nicht aus dem Speicher entfernen. Dies kann zu Speicherproblemen führen, denn wenn A dasselbe mit mehr Objekten macht, befinden sich viele Objekte im Speicher, die nicht recycelt werden können, was extrem viel Speicherplatz verbraucht.
Es ist auch möglich, dass B eine große Anzahl von Verweisen auf andere Objekte enthält und diese von B referenzierten Objekte nicht recycelt werden können. Alle diese ungenutzten Objekte verbrauchen wertvollen Speicherplatz.
3. Wie kann man Speicherlecks verhindern?
Hier finden Sie einige praktische Tipps zum Stoppen von Speicherlecks.
(1) Achten Sie auf Sammlungsklassen wie HashMap, ArrayList usw. Denn dort treten häufig Speicherlecks auf. Wenn sie als statisch deklariert werden, ist ihre Lebensdauer so lang wie die Lebensdauer der Anwendung.
(2) Achten Sie auf Ereignis-Listener und Rückrufe. Wenn ein Listener registriert, aber nicht abgemeldet wird, wenn die Klasse nicht mehr verwendet wird, tritt ein Speicherverlust auf.
(3) „Wenn eine Klasse ihren eigenen Speicher verwaltet, sollten Programmierer auf Speicherlecks achten.“ [1] Wenn eine Mitgliedsvariable eines Objekts auf andere Objekte verweist, wird sie oft nicht mehr benötigt es wird nicht mehr verwendet wird auf null gesetzt.
4. Ein kurzes Quiz: Warum verursacht die Methode substring() Speicherverluste in JDK6?
Um diese Frage zu beantworten, möchten Sie vielleicht etwas über substring() in JDK6 und 7 lesen.
Referenzen:
[1]Bloch, Joshua.Effective Java.Addison-Wesley Professional, 2008
[2]IBM Developer Work.http://www.ibm.com/developerworks/ Bibliothek /j-leaks/