Speicherleckstelle

Eine Speicherleckstelle, in der Informatik (oder Leckage, in diesem Zusammenhang), kommt vor, wenn ein Computerprogramm Gedächtnis verbraucht, aber unfähig ist, es zurück zum Betriebssystem zu veröffentlichen. In der objektorientierten Programmierung geschieht eine Speicherleckstelle, wenn ein Gegenstand im Gedächtnis versorgt wird, aber durch den laufenden Code nicht zugegriffen werden kann. Eine Speicherleckstelle hat Symptome, die mehreren anderen Problemen (sieh unten) ähnlich sind, und kann nur allgemein von einem Programmierer mit dem Zugang zum Programm-Quellcode diagnostiziert werden; jedoch beziehen sich viele Menschen auf jede unerwünschte Zunahme im Speichergebrauch als eine Speicherleckstelle, obwohl das von einer technischen Perspektive nicht ausschließlich genau ist.

Weil sie verfügbares Systemgedächtnis erschöpfen können, als eine Anwendung läuft, sind Speicherleckstellen häufig die Ursache oder ein beitragender Faktor des Softwarealterns.

Folgen

Eine Speicherleckstelle kann die Leistung des Computers durch das Reduzieren des Betrags des verfügbaren Gedächtnisses verringern. Schließlich, im Grenzfall, kann zu viel vom verfügbaren Gedächtnis zugeteilt werden, und alle oder ein Teil des Systems oder Geräts hören auf, richtig zu arbeiten, die Anwendung scheitert, oder das System verlangsamt sich unannehmbar wegen der Dresche.

Speicherleckstellen können nicht ernst oder sogar durch normale Mittel feststellbar sein. In modernen Betriebssystemen wird normales durch eine Anwendung verwendetes Gedächtnis veröffentlicht, wenn die Anwendung endet. Das bedeutet, dass ein Gedächtnis in einem Programm leckt, das nur seit einer kurzen Zeit läuft, kann nicht bemerkt werden und ist selten ernst.

Leckstellen, die viel ernster sind, schließen ein:

  • Wohin das Programm seit einer verlängerten Zeit läuft und zusätzliches Gedächtnis mit der Zeit, wie Hintergrundaufgaben auf Servern, aber besonders in eingebetteten Geräten verbraucht, die verlassen werden können, viele Jahre lang laufend.
  • Wo neues Gedächtnis oft für ehemalige Aufgaben, solcher als zugeteilt wird, wenn man die Rahmen eines Computerspieles macht, oder Video belebt hat.
  • Wo das Programm im Stande ist, um Gedächtnis — wie geteiltes Gedächtnis zu bitten —, der nicht veröffentlicht wird, selbst wenn das Programm endet.
  • Wo Gedächtnis, solcher als in einem eingebetteten System oder tragbarem Gerät sehr beschränkt wird.
  • Wo die Leckstelle innerhalb des Betriebssystems oder Speicherbetriebsleiters vorkommt.
  • Wo die Leckstelle die Verantwortung eines Systemgerät-Fahrers ist.
  • Wo das Laufen auf Betriebssysteme, der Gedächtnis auf der Programm-Beendigung nicht automatisch veröffentlicht. Häufig auf solchen Maschinen, wenn Gedächtnis verloren wird, kann es nur durch einen Neustart, ein Beispiel solch eines Systems zurückgefordert werden AmigaOS zu sein.

Ein Beispiel der Speicherleckstelle

Das folgende Beispiel, das im Pseudocode geschrieben ist, ist beabsichtigt, um zu zeigen, wie eine Speicherleckstelle, und seine Effekten geschehen kann, ohne irgendwelche Programmierkenntnisse zu brauchen. Das Programm ist in diesem Fall ein Teil von einer sehr einfachen Software, die entworfen ist, um einen Aufzug zu kontrollieren. Dieser Teil des Programms wird geführt, wann auch immer jeder innerhalb des Aufzugs den Knopf für einen Fußboden drückt.

Wenn ein Knopf gedrückt wird:

Bekommen Sie etwas Gedächtnis, das verwendet wird, um sich an die Fußboden-Zahl zu erinnern

Stellen Sie die Fußboden-Zahl ins Gedächtnis

Sind wir bereits auf dem Zielfußboden?

Wenn so, wir haben nichts, um zu tun: beendeter

Sonst:

Warten Sie, bis das Heben müßiger ist

Gehen Sie zum erforderlichen Fußboden

Veröffentlichen Sie das Gedächtnis wir haben gepflegt, sich an die Fußboden-Zahl zu erinnern

Die Speicherleckstelle würde vorkommen, wenn die gebetene Fußboden-Zahl derselbe Fußboden ist, dass das Heben auf ist; die Bedingung, für das Gedächtnis zu veröffentlichen, würde ausgelassen. Jedes Mal, wenn dieser Fall vorkommt, wird mehr Gedächtnis durchgelassen.

Fälle wie das würden keine unmittelbaren Effekten gewöhnlich haben. Leute drücken den Knopf für den Fußboden nicht häufig sie sind bereits, und jedenfalls auf, das Heben könnte genug Ersatzgedächtnis haben, dass das Hunderte oder Tausende von Zeiten zufällig konnte. Jedoch wird das Heben schließlich an Gedächtnis knapp werden. Das konnte Monate oder Jahre nehmen, so könnte es nicht trotz der gründlichen Prüfung entdeckt werden.

Die Folgen würden unangenehm sein; zumindest würde das Heben aufhören, auf Bitten zu antworten, sich zu einem anderen Fußboden zu bewegen. Wenn andere Teile des Programms Gedächtnis brauchen (ein Teil, der damit beauftragt ist, die Tür, zum Beispiel sich zu öffnen und zu schließen), dann kann jemand innen gefangen werden, da die Software die Tür nicht öffnen kann.

Die Speicherleckstelle dauert, bis das System neu gefasst wird. Zum Beispiel: Wenn die Macht des Hebens abgedreht würde, würde das Programm aufhören zu laufen. Als Macht wieder angemacht wurde, würde das Programm wiederanfangen, und das ganze Gedächtnis würde wieder verfügbar sein, aber der langsame Prozess der Speicherleckstelle würde zusammen mit dem Programm wiederanfangen, schließlich das richtige Laufen des Systems mit einem Vorurteil erfüllend.

Programmierung von Problemen

Speicherleckstellen sind ein allgemeiner Fehler in der Programmierung besonders, wenn sie Sprachen verwenden, die keine eingebaute automatische Müll-Sammlung, wie C und C ++ haben. Gewöhnlich kommt eine Speicherleckstelle vor, weil dynamisch zugeteiltes Gedächtnis unerreichbar geworden ist. Das Vorherrschen des Gedächtnisses leckt Programmfehler hat zur Entwicklung mehrerer Beseitigen-Werkzeuge geführt, um unerreichbares Gedächtnis zu entdecken. IBM Rational Purify, BoundsChecker, Valgrind, Versichert ++, und memwatch sind einige der populäreren Speichertesthilfeprogramme für C und C ++ Programme. "Konservative" Müll-Sammlungsfähigkeiten können zu jeder Programmiersprache hinzugefügt werden, die daran als eine eingebaute Eigenschaft und Bibliotheken Mangel hat, um zu tun, ist das für C und C ++ Programme verfügbar. Ein konservativer Sammler findet und protestiert am meisten, aber nicht alle, unerreichbares Gedächtnis.

Obwohl der Speicherbetriebsleiter unerreichbares Gedächtnis wieder erlangen kann, kann es nicht Gedächtnis befreien, das noch erreichbar ist und deshalb potenziell stilles nützlich. Moderne Speicherbetriebsleiter stellen deshalb Techniken für Programmierer zur Verfügung, um Gedächtnis mit unterschiedlichen Niveaus der Nützlichkeit semantisch zu kennzeichnen, die unterschiedlichen Niveaus von reachability entsprechen. Der Speicherbetriebsleiter befreit keinen Gegenstand, der stark erreichbar ist. Ein Gegenstand ist stark erreichbar, wenn es entweder direkt durch eine starke Verweisung oder indirekt durch eine Kette von starken Verweisungen erreichbar ist. (Eine starke Verweisung ist eine Verweisung, die, verschieden von einer schwachen Verweisung, einen Gegenstand hindert, gesammelter Müll zu sein.), Um das zu verhindern, ist der Entwickler dafür verantwortlich, Verweisungen nach dem Gebrauch normalerweise aufzuräumen, indem er die Verweisung auf die Null setzt, sobald es nicht mehr erforderlich ist und nötigenfalls, indem es irgendwelche Ereignis-Zuhörer im Register gelöscht wird, die starke Verweisungen auf den Gegenstand aufrechterhalten.

Im Allgemeinen ist automatisches Speichermanagement robuster und für Entwickler günstig, weil sie Freigeben-Routinen nicht durchzuführen oder sich über die Folge zu sorgen brauchen, in der Reinigung durchgeführt wird oder darüber betroffen werden, ob in einem Gegenstand noch Verweise angebracht wird. Es ist für einen Programmierer leichter zu wissen, wenn eine Verweisung nicht mehr erforderlich ist als zu wissen, wenn in einem Gegenstand nicht mehr Verweise angebracht wird. Jedoch kann automatisches Speichermanagement eine Leistung oben auferlegen, und es beseitigt alle Programmierfehler dieses Ursache-Gedächtnis Leckstellen nicht.

RAII

RAII, der für den Quellenerwerb kurz ist, Ist Initialisierung, ist eine Annäherung an das Problem, das allgemein in C ++, D, und Ada genommen ist. Es schließt das Verbinden scoped Gegenstände mit den erworbenen Mitteln und automatisch Ausgabe der Mittel ein, sobald die Gegenstände außer dem Spielraum sind. Verschieden von der Müll-Sammlung ist RAII im Vorteil des Wissens, wenn Gegenstände bestehen, und wenn sie nicht tun. Vergleichen Sie den folgenden C und C ++ Beispiele:

/* C Version * /

einschließen

Leere f (interne Nummer n)

{\

int* ordnen = calloc (n, sizeof (interne Nummer));

do_some_work (Reihe);

frei (Reihe);

}\</Quelle>

//C ++ Version

einschließen Leere f (interne Nummer n){\

std:: Vektor

do_some_work (Reihe);}\</Quelle>

Die C Version, wie durchgeführt, im Beispiel, verlangt ausführlichen deallocation; die Reihe wird (vom Haufen in den meisten C Durchführungen) dynamisch zugeteilt und setzt fort, bis ausführlich befreit, zu bestehen.

Der C ++ Version verlangt keinen ausführlichen deallocation; es wird immer automatisch vorkommen, sobald der Gegenstand aus dem Spielraum, einschließlich geht, wenn eine Ausnahme geworfen wird. Das vermeidet einige der Gemeinkosten von Müll-Sammlungsschemas. Und weil Gegenstand destructors kostenlose Quellen außer dem Gedächtnis kann, hilft RAII, das Auslaufen des Eingangs zu verhindern, und Produktionsmittel haben durch einen Griff zugegriffen, den Müll-Sammlung des Zeichens-Und-Kehrens anmutig nicht behandelt. Diese schließen offene Dateien, offene Fenster, Benutzerankündigungen, Gegenstände in einer Grafikzeichnungsbibliothek ein, fädeln Synchronisationsprimitive wie kritische Abteilungen, Netzverbindungen und Verbindungen zur Windows-Registrierung oder einer anderen Datenbank ein.

Jedoch das Verwenden ist RAII richtig nicht immer leicht und hat seine eigenen Fallen. Zum Beispiel, wenn man nicht sorgfältig ist, ist es möglich, baumelnde Zeigestöcke (oder Verweisungen) durch das Zurückbringen von Daten durch die Verweisung zu schaffen, nur das Daten zu haben, gelöscht werden, wenn sein, Gegenstand enthaltend, aus dem Spielraum geht.

D verwendet eine Kombination von RAII und Müll-Sammlung, automatische Zerstörung verwendend, wenn es klar ist, dass auf einen Gegenstand außerhalb seines ursprünglichen Spielraums und Müll-Sammlung sonst nicht zugegriffen werden kann.

Das Bezugszählen und die zyklischen Verweisungen

Modernere Müll-Sammlungsschemas basieren häufig auf einem Begriff von reachability - wenn Sie keine verwendbare Verweisung auf das fragliche Gedächtnis haben, kann er gesammelt werden. Andere Müll-Sammlungsschemas können auf dem Bezugszählen basieren, wo ein Gegenstand dafür verantwortlich ist, das nachzugehen, wie viele Verweisungen dazu hinweisen. Wenn die Zahl zur Null hinuntergeht, wie man erwartet, veröffentlicht der Gegenstand sich und erlaubt seinem Gedächtnis, zurückgefordert zu werden. Der Fehler mit diesem Modell ist, dass es mit zyklischen Verweisungen nicht fertig wird, und das ist, warum heutzutage wir bereit sind, die Last des kostspieligeren Zeichens und den Kehren-Typ von Systemen zu akzeptieren.

Der folgende Grundlegende Sehcode illustriert die kanonische bezugsaufzählende Speicherleckstelle:

Verdunkeln Sie A, B

Gehen Sie = CreateObject unter ("einige. Ding")

Satz B = CreateObject ("einige. Ding")

'An diesem Punkt die zwei Gegenstände hat jeder eine Verweisung,

Satz A.member = B

Satz B.member = ein

'Jetzt sie hat jeder zwei Verweisungen.

Gehen Sie = Nichts unter 'Sie konnten daraus noch herauskommen...

Satz B = Nichts 'Und jetzt haben Sie eine Speicherleckstelle!

Ende

</Quelle>

In der Praxis würde dieses triviale Beispiel sofort entdeckt und befestigt. In den meisten echten Beispielen misst der Zyklus von Verweisungen mehr als zwei Gegenstände ab und ist schwieriger zu entdecken.

Ein wohl bekanntes Beispiel dieser Art der Leckstelle ist zur Bekanntheit mit dem Anstieg von AJAX Programmierung von Techniken in WWW-Browsern gekommen. Code von Javascript, der ein DOM Element mit einem Ereignis-Dressierer vereinigt hat und gescheitert hat, die Verweisung vor dem Herausnehmen zu entfernen, würde Gedächtnis durchlassen (AJAX Webseiten behalten einen gegebenen DOM lebendigen für den viel längeren als traditionelle Webseiten, so war diese Leckstelle viel mehr offenbar).

Effekten

Wenn ein Programm eine Speicherleckstelle hat und sein Speichergebrauch fest zunimmt, wird es kein unmittelbares Symptom gewöhnlich geben. Jedes physische System hat einen begrenzten Betrag des Gedächtnisses, und wenn die Speicherleckstelle nicht enthalten wird (zum Beispiel, durch das Wiederstarten des Auslaufen-Programms), wird es früher oder später anfangen, Probleme zu verursachen.

Betriebssysteme der Arbeitsfläche des des grössten Teiles modernen Verbrauchers haben sowohl Hauptgedächtnis, das in RAM-Mikrochips als auch sekundärer Lagerung wie eine Festplatte physisch aufgenommen wird. Speicherzuteilung ist dynamisch - jeder Prozess bekommt so viel Gedächtnis, wie es bittet. Aktive Seiten werden ins Hauptgedächtnis für den schnellen Zugang übertragen; untätige Seiten werden zur sekundären Lagerung gedrängt, Platz, wie erforderlich, zu machen. Wenn ein einzelner Prozess anfängt, einen großen Betrag des Gedächtnisses zu verbrauchen, besetzt er gewöhnlich immer mehr des Hauptgedächtnisses, andere Programme zur sekundären Lagerung - gewöhnlich sich bedeutsam verlangsamende Leistung des Systems stoßend. Selbst wenn das Auslaufen-Programm begrenzt wird, kann es für andere Programme Zeit in Anspruch nehmen, um zurück ins Hauptgedächtnis, und für die Leistung zu tauschen, um zum normalen zurückzukehren.

Wenn das ganze Gedächtnis auf einem System erschöpft wird (ob es virtuelles Gedächtnis oder nur Hauptgedächtnis, solcher als auf einem eingebetteten System gibt), wird jeder Versuch, mehr Gedächtnis zuzuteilen, scheitern. Das verursacht gewöhnlich das Programm, das versucht, das Gedächtnis zuzuteilen, um sich zu begrenzen, oder eine Segmentationsschuld zu erzeugen. Einige Programme werden entworfen, um sich von dieser Situation (vielleicht durch das Zurückgreifen auf vorvorbestelltes Gedächtnis) zu erholen. Das erste Programm, um den aus dem Gedächtnis zu erfahren, kann oder kann nicht das Programm sein, das die Speicherleckstelle hat.

Einige stark mehrbeanspruchende Betriebssysteme haben spezielle Mechanismen, sich mit einer Bedingung aus dem Gedächtnis, wie Tötung von Prozessen aufs Geratewohl zu befassen (der "unschuldige" Prozesse betreffen kann), oder Tötung des größten Prozesses im Gedächtnis (der vermutlich derjenige ist, der das Problem verursacht). Einige Betriebssysteme haben eine Speichergrenze pro Prozess, um irgendwelches Programm an hogging das ganze Gedächtnis auf dem System zu verhindern. Der Nachteil zu dieser Einordnung ist, dass das Betriebssystem manchmal wiederkonfiguriert werden muss, um richtige Operation von Programmen zu erlauben, die legitim große Beträge des Gedächtnisses, wie diejenigen verlangen, die sich mit Grafik, Video oder wissenschaftlichen Berechnungen befassen.

Wenn die Speicherleckstelle im Kern ist, wird das Betriebssystem selbst wahrscheinlich scheitern. Computer ohne hoch entwickeltes Speichermanagement, wie eingebettete Systeme, können auch von einer beharrlichen Speicherleckstelle völlig scheitern.

Öffentlich zugängliche Systeme wie Webserver oder Router sind für Angriffe der Leugnung des Dienstes anfällig, wenn ein Angreifer eine Folge von Operationen entdeckt, die eine Leckstelle auslösen können. Solch eine Folge ist als eine Großtat bekannt.

Ein "Sägezahn"-Muster der Speicheranwendung kann ein Hinweis einer Speicherleckstelle sein, wenn die vertikalen Fälle mit dem Neustart oder den Anwendungswiederanfängen zusammenfallen. Sorge sollte obwohl genommen werden, weil Müll-Sammlungspunkte auch solch ein Muster verursachen konnten.

Andere Speicherverbraucher

Bemerken Sie, dass ständig Erhöhung des Speichergebrauchs nicht notwendigerweise Beweise einer Speicherleckstelle ist. Einige Anwendungen werden jemals zunehmende Beträge der Information im Gedächtnis (z.B als ein geheimes Lager) versorgen. Wenn das geheime Lager so groß wachsen kann, um Probleme zu verursachen, kann das eine Programmierung oder Designfehler sein, aber ist nicht eine Speicherleckstelle, weil die Information nominell im Gebrauch bleibt. In anderen Fällen können Programme einen unvernünftig großen Betrag des Gedächtnisses verlangen, weil der Programmierer angenommen hat, dass Gedächtnis immer für eine besondere Aufgabe genügend ist; zum Beispiel könnte ein Grafikdateiverarbeiter durch das Lesen des kompletten Inhalts einer Bilddatei und die Speicherung von all dem ins Gedächtnis, etwas anfangen, was nicht lebensfähig ist, wo ein sehr großes Image verfügbares Gedächtnis überschreitet.

Um es ein anderer Weg zu stellen, entsteht eine Speicherleckstelle aus einer besonderen Art, Fehler, und ohne Zugang zum Programm-Code, jemand zu programmieren, sehend, dass Symptome nur glauben können, dass es eine Speicherleckstelle geben könnte. Es würde besser sein, Begriffe wie "ständig zunehmender Speichergebrauch" zu gebrauchen, wo keine solche Innenkenntnisse bestehen.

Ein einfaches Beispiel in C

Die folgende C-Funktion lässt absichtlich Gedächtnis durch das Verlieren des Zeigestocks zum zugeteilten Gedächtnis durch. Da die Programm-Schleifen, für immer die Speicherzuteilungsfunktion nennend, aber ohne die Adresse zu sparen, es schließlich (das Zurückbringen) scheitern wird, wenn kein Gedächtnis mehr für das Programm verfügbar ist. Weil die Adresse jeder Zuteilung nicht versorgt wird, ist es unmöglich, einigen der vorher zugeteilten Blöcke zu befreien. Es sollte bemerkt werden, dass, allgemein, das Betriebssystem echte Speicherzuteilung verzögert, bis etwas darin geschrieben wird. So endet das Programm, wenn virtuelle Adressen aus laufen (pro Prozess-Grenzen oder 2 bis 4 GiB auf IA-32 oder viel mehr auf x86-64 Systemen) und es keinen echten Einfluss auf den Rest des Systems geben kann.

einschließen

int Haupt(Leere)

{\

/* das ist eine unendliche Schleife, die die Malloc-Funktion der nennt

* teilt das Gedächtnis zu, aber ohne die Adresse des zu sparen

* zugeteilter Platz * /

während (malloc (50));/* malloc wird UNGÜLTIG früher oder später, erwartet zurückkehren, des Gedächtnisses * / zu fehlen

kehren Sie 0 zurück;/* befreien das zugeteilte Gedächtnis durch das Betriebssystem selbst nach Programm-Ausgängen * /

}\</Quelle>

Siehe auch

  • Pufferüberschwemmung
  • Speichermanagement
  • Speichertesthilfeprogramm
  • nmon (kurz für den Monitor von Nigel) ist ein populäres Systemmonitor-Werkzeug für AIX und Linux Betriebssysteme.

Artikel


Hauptfolge / Molekular Augenhöhlen-
Impressum & Datenschutz