Speicherleck - LinkFang.de





Speicherleck


Speicherleck (englisch memory leak, gelegentlich auch Speicherloch oder kurz memleak) bezeichnet einen Fehler in der Speicherverwaltung eines Computerprogramms, der dazu führt, dass es einen Teil des Arbeitsspeichers zwar belegt, diesen jedoch weder freigibt noch nutzt.

Problematik

Arbeitsspeicher ist ein nur in endlicher Menge verfügbares Betriebsmittel, das einem Programm auch nicht ohne weiteres wieder entzogen werden darf. Wenn ein Programm durch Speicherlecks zunehmend mehr Arbeitsspeicher belegt, kann es dazu kommen, dass die Leistungsfähigkeit des Computers sinkt, da Teile des Arbeitsspeichers ausgelagert werden müssen. Wenn die Menge an Speicher, die ein Prozess belegen kann, beschränkt wurde, ist es dem Programm irgendwann nicht mehr möglich, weiter Speicher zu allozieren und es kommt zu einem Programmfehler. Bei Betriebssystemen mit unzureichendem Speicherschutz (z. B. bei Embedded-Systemen) kann im schlimmsten Fall die Überbelegung des Speichers dazu führen, dass auch Teile des Betriebssystems nicht mehr korrekt ausgeführt werden können und das System abstürzt.

Lösungsmöglichkeiten

Der Speicher, der höchstens von einem Prozess belegt werden darf, kann durch das Betriebssystem beschränkt werden. Das behebt den ursprünglichen Fehler nicht, aber begrenzt die Auswirkungen auf andere Prozesse.

Um Speicherlecks aufzuspüren existieren mehrere Möglichkeiten:

  1. Analyse der Referenzen auf Speicherbereiche (z. B. Smart Pointer).
  2. Analyse des Quelltexts auf formale Korrektheit.
  3. Analyse konkreter Laufzeit-Situationen im Rahmen eines Software-Tests.

Unter Linux existiert eine Kernelfunktion, der OOM-Killer (engl. out of memory killer), die zum Einsatz kommt, wenn alle Versuche fehlschlugen, Speicher zu allozieren. Sie wählt unter den laufenden Prozessen u. a. denjenigen mit dem höchsten Speicherbedarf, der kürzesten Laufzeit und der niedrigsten Priorität und beendet diesen zwangsweise. Nach Beendigung des Prozesses wird aller von ihm belegter Arbeitsspeicher wieder freigegeben.[1]

Automatische Speicherbereinigung

Falls die verwendete Laufzeitumgebung eine automatische Speicherbereinigung bereitstellt, versucht diese zu ermitteln, auf welche Speicherbereiche ein Prozess nicht mehr zugreift. Stellt die Laufzeitumgebung fest, dass ein belegter Speicherbereich für das Programm nicht mehr erreichbar ist, wird dieser wieder freigegeben. Nicht mehr erreichbar heißt in diesem Zusammenhang, dass keine gültige Referenz auf den belegten Speicherbereich mehr existiert. Speicherlecks können dabei dennoch entstehen, wenn der Speicher für das Programm noch erreichbar ist, d. h. es eine Referenz auf den Speicher hält, ihn aber dennoch nicht mehr verwendet.

Explizite Speicherfreigabe

Im Gegensatz zur automatischen Speicherbereinigung muss der Anwendungsentwickler bei einer manuellen Speicherverwaltung explizit dynamisch Speicherbereiche wieder freigeben. Versäumt er dies bspw. am Ende einer Funktion, wird anschließend die Referenz auf den noch reservierten Speicher gelöscht und der Bereich kann nicht mehr freigegeben werden.

Systematische Tests

Durch systematisches Testen mit Hilfe entsprechender Werkzeuge, die mit einer gewissen Sicherheit feststellen können, welche Speicherbereiche einem Speicherleck zuzuordnen sind, kann man den Problemen der formalen Verifikation entgehen.

Ein bekanntes solches Werkzeug (auf Linux-Systemen) ist memcheck von Valgrind. Es führt eine Liste der allozierten Speicherbereiche mit und an welcher Stelle im Programm die Allokation stattfand. Bei Programmende überprüft es, ob alle allozierte Bereiche auch wieder freigegeben wurden. In sehr einfachen oder sehr gravierenden Fällen kann es ausreichen, nur den Speicherverbrauch eines Prozesses im zeitlichen Verlauf zu beobachten.

RAII

Eine Programmiertechnik, die Speicherlecks verhindern kann, ist RAII (Ressourcenbelegung ist Initialisierung). Hierbei wird der Speicherbereich einer Variablen bei ihrer Initialisierung reserviert und beim Verlassen ihres Gültigkeitsbereichs automatisch wieder freigegeben. Das hat gegenüber der automatischen Speicherverwaltung den Vorteil, dass die „Lebensdauer“ eines Objekts in der Regel genau bekannt ist.

Formale Verifikation

Durch einen Korrektheitsbeweis können insbesondere auch Speicherlecks entdeckt werden. Dieses Verfahren ist jedoch sehr zeitaufwendig und benötigt Expertenwissen. Die auf Speicherlecks spezialisierte Frage kann auch computergestützt mittels Statischer Code-Analyse untersucht werden.

Beispiele

C

Das bekannteste Beispiel für fehlende automatische Speicherverwaltung ist die Sprache C. Neuer Speicher wird in C-Programmen durch die Funktion malloc angefordert. Dabei liefert malloc einen Zeiger auf den Anfang des entsprechenden Speicherbereichs. Dieser Verweis ist notwendig, um den Speicher mittels geeignetem Code wieder freizugeben (mittels der Funktion free). Geht der Zeiger verloren oder wird verändert, kann der Prozess nicht mehr auf diesen Speicher zugreifen und ihn damit auch nicht freigeben.

Das folgende Beispiel zeigt die Entstehung solch eines Speicherlecks:

#include <stdlib.h>
 
int main(void)
{
   int *a; /* Zeiger auf einen als Ganzzahl interpretierten Speicherbereich */
 
   /* Speicher für Zeiger reservieren. */
   a = malloc(sizeof(int));
   /* ... */
   a = malloc(sizeof(int));   /* Zeiger auf zuvor allozierten Speicher wird überschrieben. */
 
   free(a);  /* Nur der zweite Speicherblock wird freigegeben --> Speicherleck */
 
   return EXIT_SUCCESS;
}

Ab dem zweiten a = malloc() ist es nicht mehr möglich, auf den Speicherbereich zuzugreifen, auf den a zuvor verwies. Der Bereich kann dann regulär nicht mehr vom Programm freigegeben werden.

Automatische Speicherbereinigung

Das folgende Beispiel in Java zeigt, dass alleine der Ansatz der automatischen Speicherbereinigung nicht reicht, um Speicherlecks aufzudecken:

private static List<Integer> nummern = new ArrayList<>();
public void erzeugeSpeicherleck() {
  for (int i=1; i<10000; i++)
    nummern.add(i);
}
// kein weiterer lesender Zugriff auf die List nummern

Man erkennt hier, dass der Speicherbedarf ständig anwächst, es handelt sich also um ein Speicherleck, da kein lesender Zugriff mehr auf die Listen-Einträge erfolgt. Dieser Fehler wäre recht leicht durch statische Analyse zu erkennen, wohingegen der Graph aus Referenzen und Speicherbereichen den Fehler nicht erkennen lässt.

Weblinks

Einzelnachweise

  1. linux-mm.org

Kategorien: Programmfehler | Speicherverwaltung

Quelle: Wikipedia - http://de.wikipedia.org/wiki/Speicherleck (Vollständige Liste der Autoren des Textes [Versionsgeschichte])    Lizenz: CC-by-sa-3.0

Änderungen: Alle Bilder mit den meisten Bildunterschriften wurden entfernt. Ebenso alle zu nicht-existierenden Artikeln/Kategorien gehenden internen Wikipedia-Links (Bsp. Portal-Links, Redlinks, Bearbeiten-Links). Entfernung von Navigationsframes, Geo & Normdaten, Mediadateien, gesprochene Versionen, z.T. ID&Class-Namen, Style von Div-Containern, Metadaten, Vorlagen, wie lesenwerte Artikel. Ansonsten sind keine Inhaltsänderungen vorgenommen worden. Weiterhin kann es durch die maschinelle Bearbeitung des Inhalts zu Fehlern gerade in der Darstellung kommen. Darum würden wir jeden Besucher unserer Seite darum bitten uns diese Fehler über den Support mittels einer Nachricht mit Link zu melden. Vielen Dank!

Stand der Informationen: August 201& - Wichtiger Hinweis: Da die Inhalte maschinell von Wikipedia übernommen wurden, ist eine manuelle Überprüfung nicht möglich. Somit garantiert LinkFang.de nicht die Richtigkeit und Aktualität der übernommenen Inhalte. Sollten die Informationen mittlerweile fehlerhaft sein, bitten wir Sie darum uns per Support oder E-Mail zu kontaktieren. Wir werden uns dann innerhalb von spätestens 10 Tagen um Ihr Anliegen kümmern. Auch ohne Anliegen erfolgt mindestens alle drei Monate ein Update der gesamten Inhalte.