Was genau ist ein Speicherleck ?
Und wie wirkt sich das auf das System aus, auf dem das Programm läuft?
Was genau ist ein Speicherleck ?
Und wie wirkt sich das auf das System aus, auf dem das Programm läuft?
Wenn Ihr Prozess ständig Speicher vom Betriebssystem anfordert und nie etwas davon freigibt, werden Sie irgendwann mehr Speicher verwenden, als physisch im Rechner vorhanden ist. An diesem Punkt wird das Betriebssystem zunächst auf virtuellen Speicher ausweichen (was die Leistung verschlechtert), falls es welchen hat, und irgendwann wird Ihr Prozess einen Punkt erreichen, an dem das Betriebssystem ihm keinen weiteren Speicher mehr zuweisen kann, weil Sie die maximale Menge an adressierbarem Speicher (4 GB bei einem 32-Bit-Betriebssystem) überschritten haben.
Hierfür gibt es im Wesentlichen zwei Gründe: Sie haben Speicher zugewiesen und den Zeiger darauf verloren (er ist für Ihr Programm unerreichbar geworden), so dass Sie ihn nicht mehr freigeben können. Das ist das, was die meisten Leute ein Speicherleck nennen. Es kann aber auch sein, dass Sie einfach nur Speicher zuweisen und ihn nie wieder freigeben, weil Ihr Programm faul ist. Das ist dann zwar kein Speicherleck, aber die Probleme, die Sie bekommen, sind letztlich die gleichen.
Ein Speicherleck liegt vor, wenn Ihr Code Speicher zuweist und dann den Überblick darüber verliert, einschließlich der Möglichkeit, ihn später wieder freizugeben.
In C kann dies zum Beispiel mit der einfachen Sequenz geschehen:
void *pointer = malloc (2718); // Alloc, store address in pointer.
pointer = malloc (31415); // And again.
free (pointer); // Only frees the second block.
Der ursprüngliche Speicherblock wird weiterhin zugewiesen, aber da pointer
nicht mehr darauf verweist, haben Sie keine Möglichkeit, es zu befreien.
Diese Sequenz ist für sich genommen gar nicht so schlecht (na ja, sie est schlecht, aber die Auswirkungen sind es vielleicht nicht). Probleme treten in der Regel dann auf, wenn Sie es wiederholt tun. Zum Beispiel in einer Schleife oder in einer Funktion, die wiederholt aufgerufen wird:
static char firstDigit (int val) {
char *buff = malloc (100); // Allocates.
if (val < 0)
val = -val;
sprintf (buff, "%d", val);
return buff[0]; // But never frees.
}
Jedes Mal, wenn Sie diese Funktion aufrufen, werden Sie die hundert Bytes (plus alle Haushaltsinformationen) verlieren.
Und ja, Speicherlecks wirken sich auf andere Dinge aus. Aber die Auswirkungen sollten begrenzt sein.
Dies wird sich schließlich auf den Prozess auswirken, der undicht ist, da ihm der Adressraum für die Zuweisung weiterer Objekte ausgeht. Das mag zwar nicht unbedingt bei kurzlebigen Prozessen eine Rolle spielen, werden langlebige Prozesse irgendwann scheitern.
Ein vernünftiges Betriebssystem (und dazu gehört auch Windows) begrenzt jedoch die Ressourcen, die ein einzelner Prozess nutzen kann, was die Auswirkungen auf die andere Prozesse. Da in modernen Umgebungen der virtuelle vom physischen Speicher getrennt ist, besteht die einzige wirkliche Auswirkung, die von Prozess zu Prozess übertragen werden kann, darin, dass ein Prozess versucht, seinen gesamten virtuellen Speicher ständig im physischen Speicher zu halten, wodurch die Zuweisung dieses physischen Speichers an andere Prozesse verringert wird.
Aber selbst wenn ein einzelner Prozess Gigabytes an Speicher leckt, wird der Speicher selbst nicht von dem Prozess verwendet (der Kernpunkt des Lecks ist, dass der Prozess den Zugriff auf den Speicher verloren hat). Und da er nicht verwendet wird, wird das Betriebssystem ihn mit ziemlicher Sicherheit auf die Festplatte auslagern und nie wieder in den Arbeitsspeicher zurückholen müssen.
Natürlich verbraucht es Swap-Speicherplatz und dass kann sich auf andere Prozesse auswirken, aber die Menge der Festplatte überwiegt bei weitem die Menge des physischen RAM.
Wenn Sie Speicherplatz verlieren, bedeutet dies, dass Sie dynamisch Objekte erstellen, diese aber nicht zerstören. Wenn das Leck groß genug ist, geht Ihrem Programm irgendwann der Adressraum aus, und künftige Zuweisungsversuche schlagen fehl (was wahrscheinlich dazu führt, dass Ihre Anwendung beendet wird oder abstürzt, denn wenn Sie Speicherlecks haben, können Sie wahrscheinlich auch nicht sehr gut damit umgehen), oder das Betriebssystem hält Ihren Prozess an, wenn es versucht, zu viel Speicher zuzuweisen.
Außerdem müssen Sie bedenken, dass in C++ viele Objekte Destruktoren haben: Wenn Sie ein dynamisch zugewiesenes Objekt nicht zerstören können, wird sein Destruktor nicht aufgerufen.
Ein Speicherleck entsteht, wenn ein Programm dynamischen Speicher zuweist und dann alle Zeiger auf diesen Speicher verliert, so dass es ihn weder adressieren noch freigeben kann. Der Speicher bleibt als zugewiesen markiert, so dass er nie zurückgegeben wird, wenn das Programm mehr Speicher anfordert.
Das Programm erschöpft die begrenzten Ressourcen mit einer gewissen Geschwindigkeit. Abhängig von der Größe des Arbeitsspeichers und der Auslagerungsdatei kann dies dazu führen, dass entweder das Programm irgendwann die Meldung "can't allocate memory" erhält oder dass dem Betriebssystem sowohl der physische Arbeitsspeicher als auch die Auslagerungsdatei ausgeht und nur ein Programm die Meldung "can't allocate memory" erhält. Letzteres kann bei einigen Betriebssystemen schwerwiegende Folgen haben - wir sehen manchmal, dass Windows XP komplett zusammenbricht und wichtige Dienste nicht mehr funktionieren, wenn der extreme Speicherverbrauch eines Programms den gesamten Speicher ausschöpft. In diesem Fall besteht die einzige Möglichkeit, das Problem zu beheben, darin, das System neu zu starten.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.