Frage

Wir haben gelegentlich Probleme wurde immer wodurch unsere langlaufende Server-Prozesse (läuft auf Windows Server 2003) aufgrund eines Speicherzuordnungsfehler eine Ausnahme ausgelöst haben. Unser Verdacht ist diese Zuführungen zu Speicherfragmentierung versagen fällig.

Deshalb haben wir bereits bei einigen alternativen Speicherzuweisungsmechanismen suchen, der uns helfen kann, und ich hoffe, jemand kann mir sagen, das beste:

1) Verwenden Sie Windows Low-Fragmentierung Heap

2) jemalloc - wie verwendet in Firefox 3

3) Doug Lea malloc

Unser Server-Prozess entwickelt wird mit plattformübergreifende C ++ Code, so würde jede Lösung idealerweise Cross-Plattform sein, auch (bis * nichts Betriebssysteme leiden unter dieser Art von Speicherfragmentierung?).

Auch bin ich recht in der Annahme, dass LFH jetzt die Standard-Speicherzuordnungsmechanismus für Windows Server 2008 / Vista ist? ... Werden meine aktuellen Probleme „go away“, wenn unsere Kunden einfach ihre Server-Betriebssystem-Upgrade?

War es hilfreich?

Lösung

Erstens, ich stimme mit den anderen Plakaten, die eine Ressource Leck vorgeschlagen. Sie wollen wirklich, dass ausschließen zuerst.

Wir hoffen, der Heap-Manager Sie sind zur Zeit hat eine Art, die tatsächliche gesamte freie Speicherplatz im Heap zur Verfügung auskippen (über alle kostenlos Blöcke) und auch die Gesamtzahl der Blöcke, dass es verteilt über. Wenn die durchschnittliche freie Blockgröße relativ klein ist im Vergleich zur gesamten freien Speicherplatz im Heap, dann haben Sie ein Fragmentierungsproblem haben. Alternativ, wenn Sie die Größe des größten freien Blocks und vergleichen Sie das mit der gesamten freien Speicherplatz Dump können, werden feststellen, dass das Gleiche erreichen. Der größte freie Block würde über alle Blöcke klein im Verhältnis zu der Gesamt kostenlos Raum zur Verfügung, wenn Sie in der Fragmentierung ausgeführt werden.

Um ganz klar zu dem oben genannten, in allen Fällen sprechen wir über kostenlos Blöcke in dem Heap, nicht die zugewiesenen Blöcke in dem Heap. In jedem Fall werden, wenn die oben genannten Bedingungen nicht erfüllt ist, dann sind Sie tun hat ein Leck Situation von einer Art.

Also, wenn Sie ein Leck ausgeschlossen haben, können Sie mit einem besseren allocator betrachten. Doug Lea malloc in der Frage vorgeschlagen ist ein sehr gutes Allocator für allgemeine Anwendungen und sehr robust die meisten der Zeit. Anders ausgedrückt, hat es an der Zeit gewesen getestet sehr gut für die meisten jede Anwendung zu arbeiten. Allerdings ist kein Algorithmus ideal für alle Anwendungen und jeder Management-Algorithmus Ansatz kann durch die richtigen pathelogical Bedingungen gebrochen werden dagegen Design ist.

Warum haben Sie ein Fragmentierungsproblem - Quellen der Fragmentierungsprobleme sind verursacht durch das Verhalten einer Anwendung und haben mit stark unterschiedlichen Zuordnung Lebensdauern in der gleichen zu tun Speicher-Arena. Das heißt, einige Objekte zugeordnet und befreit regelmäßig, während andere Arten von Objekten für längere Zeit alle im gleichen Heap bestehen ..... denken Sie an die längere Lebensdauer als diejenigen Löcher in größere Bereiche der Arena stoßen und dadurch verhindern, dass die koaleszieren von benachbarten Blöcken, die freigegeben wurden.

diese Art von Problem zu beheben, das Beste, was man tun kann, ist logisch den Heap in Unter Arenen unterteilt, wo das Lebensdauern ähnlicher sind. In der Tat wollen Sie einen vorübergehenden Haufen und einen beständigen Stapel oder Haufen, dass Gruppe Dinge ähnlichen Lebensdauerns.

Einige andere haben einen anderen Ansatz vorgeschlagen, um das Problem zu lösen, die die Zuordnungsgrößen mehr ähnlich oder identisch zu versuchen, ist zu machen, aber das ist weniger ideal, weil es eine andere Art von Fragmentierung erzeugt interne Fragmentierung genannt -, die den verschwendeten in Kraft ist Platz Sie haben mehr Speicher im Block Zuweisung als Sie benötigen.

Darüber hinaus mit einem guten Haufen allocator, wie Doug Lea, so dass die Blockgrößen ähnlicher ist nicht erforderlich, da der Verteiler wird bereits eine Leistung von zwei Größen Bucketing Schema tun, dass es völlig unnötig, um künstlich die Zuordnungsgrößen anpassen geben machen (malloc) - in der Tat, sein Heap-Manager macht das für Sie automatisch viel robuster als die Anwendung in der Lage sein werden, um Anpassungen vorzunehmen

.

Andere Tipps

Ich glaube, Sie haben versehentlich einen Speicherverlust zu früh ausgeschlossen. Selbst ein winziges Speicherleck eine schwere Speicherfragmentierung verursachen kann.

Ihre Anwendung Unter der Annahme, verhält sich wie folgt zusammen:
Zuteilen 10MB
Zuteilen 1 Byte
Kostenloser 10MB
(Oops, wir haben nicht das 1 Byte befreien, aber wer kümmert sich um ein winziges Byte)

Dies scheint ein sehr kleines Leck, Sie werden es kaum bemerken, wenn die Speichergröße nur die aufteilbaren Gesamt Überwachung . Aber das Leck schließlich wird Ihr Anwendungsspeicher wie folgt aussehen:
.
.
Free - 10MB
.
.
[Zugewiesene -1 Byte]
.
.
Free - 10MB
.
.
[Zugewiesene -1 Byte]
.
.
Free - 10MB
.
.

Dieses Leck wird nicht bemerkt werden ... bis 11MB
zuordnen möchten Angenommen, Ihre minidumps hatte volle Speicherinfo enthält, empfehle ich mit DebugDiag auf mögliche undichte Stellen zu erkennen. Im generierten Speicher Bericht sorgfältig prüfen, die Zuweisung count (nicht Größe) .

Wie Sie vorschlagen, Doug Lea malloc könnte gut funktionieren. Es ist Cross-Plattform und es wird in Versand Code verwendet. Zumindest sollte es leicht sein, in den Code für den Test zu integrieren.

Nachdem in festen Speicherumgebungen für eine Reihe von Jahren gearbeitet wird diese Situation sicherlich ein Problem, auch in nicht fest Umgebungen. Wir haben gefunden, dass die CRT Verteilern in Bezug auf die Leistung (Geschwindigkeit, Effizienz der verschwendeten Speicherplatz, etc.) ziemlich schlecht stinken neigen. Ich glaube fest daran, dass, wenn Sie umfangreiche Notwendigkeit einer guten Speicherzuordner über einen langen Zeitraum haben, sollten Sie Ihre eigenen schreiben (oder sehen, ob so etwas wie dlmalloc funktioniert). Der Trick ist immer etwas geschrieben, die mit dem Zuordnungsmuster arbeitet, und das hat mehr mit Memory Management-Effizienz zu tun, wie fast alles andere.

Geben Sie dlmalloc versuchen. Ich kann es auf jeden Fall einen Daumen aufgeben. Es ist ziemlich auch abstimmbar, so dass Sie möglicherweise in der Lage sein, mehr Effizienz zu erhalten, indem einige der Kompilierung Optionen zu ändern.

Ehrlich gesagt, sollten Sie nicht auf die Dinge hängen „going away“ mit neuen OS-Implementierungen. Ein Service Pack, Patch oder eine andere neue OS N Jahre später könnte das Problem noch schlimmer. Auch für Anwendungen, die einen robusten Speichermanager fordern, nicht über die Lager-Versionen verwenden, die mit Ihrem Compiler zur Verfügung stehen. Finden Sie, dass für Ihre Situation funktioniert. Beginnen Sie mit dlmalloc und stimmen Sie es zu sehen, wenn Sie das Verhalten bekommen kann, die am besten für Ihre Situation.

Sie können helfen, die Fragmentierung zu reduzieren, indem die Menge zu reduzieren Sie ausplanen zuweisen.

z. sagen für einen Webserver eine serverseitige Skript ausgeführt wird, kann es eine Zeichenfolge zur Ausgabe der Seite erstellen. Statt Aufteilung und diese Zeichenfolgen für jede Anfrage das Aufheben von Zuweisungen, halten nur einen Pool von ihnen, so dass Ihr nur die Zuteilung, wenn Sie mehr benötigen, aber Ihr nicht freigibt, (was bedeutet, nach einer Weile die Situation bekommen Sie auch nicht mehr die Zuteilung, weil Sie genug)

Sie können mit _CrtDumpMemoryLeaks (); Speicherlecks in den Debug-Fenster zu werfen, wenn ein Debug-Build ausgeführt wird, aber ich glaube, das ist spezifisch für die Visual C-Compiler. (Es ist in Crtdbg.h)

Ich würde ein Leck vermuten, bevor Fragmentierung Verdacht.

Für die speicherintensive Datenstrukturen, könnten Sie zu einem wiederverwendbaren Speicherpool-Mechanismus wechseln. Sie könnten auch in der Lage sein, mehr Material auf dem Stapel zu verteilen, wie auf den Heap dagegen, aber in der Praxis, die nicht einen großen Unterschied machen, denke ich.

Ich würde ein Tool wie valgrind Feuer oder eine intensive Protokollierung für Ressourcen suchen nicht freigegeben werden.

@nsaners - Ich bin mir ziemlich sicher, dass das Problem ist, nach unten zu Speicherfragmentierung. Wir haben analysiert minidumps diesem Punkt ein Problem, wenn ein großer (5-10mb) Teil des Speichers zugeordnet wird. Wir haben überwachten auch den Prozess (Vor-Ort-und in der Entwicklung) für Speicherlecks zu überprüfen - nicht nachgewiesen wurden (der Speicherbedarf im Allgemeinen sehr gering ist)

.

Das Problem auf Unix geschieht, obwohl es in der Regel nicht so schlimm ist.

Der Low-framgmentation Haufen half uns, aber meine Mitarbeiter schwören auf Smart-Heap (Es ist seit Jahren Cross-Plattform in ein paar unserer Produkte verwendet wurden). Leider aufgrund anderer Umstände können wir nicht Smart-Heap diese Zeit nutzen.

Wir freuen uns auch bei Block / Chunking Aufteilung und versuchen Umfang versierte Pools / Strategien zu haben, das heißt, langfristige Dinge hier, ganz Anfrage, was es, kurzfristig Dinge da drüben, etc.

Wie üblich können Sie in der Regel Speicher verschwenden einige Geschwindigkeit zu gewinnen.

Diese Technik ist für einen allgemeinen Zweck allocator nicht sinnvoll, aber es hat seinen Platz.

Im Grunde ist die Idee, einen Zuteiler zu schreiben, die Speicher aus einem Pool gibt, wo alle Zuweisungen gleich groß sind. Dieser Pool kann nie fragmentiert werden, weil jeder Block so gut wie andere. Sie können die Speicherverschwendung, indem mehrere Pools mit unterschiedlicher Größe Brocken und wählen Sie die kleinste Blockgröße Pool, der ist immer noch größer als die angeforderte Menge reduzieren. Ich habe diese Idee zu erstellen Verteilern verwendet, die in O ausgeführt (1).

Die einfache, schnelle und schmutzige Lösung ist die Anwendung in mehrere Verfahren zu teilen, sollten Sie frische HEAP erhalten bei jedem Erstellen Sie den Vorgang.

Ihr Gedächtnis und Geschwindigkeit könnte ein Bit (Swapping) leiden, aber schnelle Hardware und große RAM sollte helfen können.

Dies war alt UNIX Trick mit Dämonen, wenn Threads hat bisher noch existierte.

Wenn Sie Win32 sprechen - können Sie versuchen, etwas zu quetschen durch LARGEADDRESSAWARE verwenden. Sie müssen ~ 1 Gb zusätzliche defragmentierte Speicher so Ihre Anwendung es mehr fragmentieren wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top