Ich hatte gerade ein Vorstellungsgespräch, bei dem ich gebeten wurde, ein Speicherleck mit Java zu erstellen.
Unnötig zu sagen, dass ich mir ziemlich dumm vorkam, weil ich keine Ahnung hatte, wie ich überhaupt ein solches Leck erstellen sollte.
Wie würde ein Beispiel aussehen?
Eine einfache Möglichkeit ist, ein HashSet mit einem falschen (oder nicht vorhandenen) hashCode()
oder equals()
zu verwenden und dann immer wieder "Duplikate" hinzuzufügen. Anstatt Duplikate zu ignorieren, wie es eigentlich sein sollte, wird die Menge nur immer größer und Sie werden nicht in der Lage sein, sie zu entfernen.
Wenn Sie wollen, dass diese schlechten Schlüssel/Elemente in der Nähe bleiben, können Sie ein statisches Feld verwenden wie
class BadKey {
// no hashCode or equals();
public final String key;
public BadKey(String key) { this.key = key; }
}
Map map = System.getProperties();
map.put(new BadKey("key"), "value"); // Memory leak even if your threads die.
Vielleicht durch die Verwendung von externem nativen Code über JNI?
Mit reinem Java ist das fast unmöglich.
Dabei handelt es sich jedoch um ein "Standard"-Speicherleck, bei dem Sie nicht mehr auf den Speicher zugreifen können, der aber immer noch im Besitz der Anwendung ist. Sie können stattdessen Verweise auf unbenutzte Objekte behalten oder Streams öffnen, ohne sie anschließend zu schließen.
Erstellen Sie eine statische Map und fügen Sie ihr immer wieder feste Referenzen hinzu. Diese werden nie GC'd sein.
public class Leaker {
private static final Map<String, Object> CACHE = new HashMap<String, Object>();
// Keep adding until failure.
public static void addToCache(String key, Object value) { Leaker.CACHE.put(key, value); }
}