2010-11-27 8 views
9

Welche Möglichkeiten gibt es, um den Speicherbedarf in C-Programmen unter Linux (* nix) zu minimieren?Minimieren des Speicherbedarfs in C-Programmen

Soweit ich weiß, verwendet libc malloc() entweder brk() oder mmap(). Speicher, der mit brk() zugewiesen wurde, kann wegen Speicherfragmentierung normalerweise nicht zurückgegeben werden.

Mein Programm sollte 24/7 arbeiten und es eine Menge malloc() - s und free() - s. Nach dem Start geht RSS auf etwa 100 MB. Es ist zu viel, weil ich sicher weiß, dass in einem bestimmten Moment weniger als 100 MB Daten im Speicher sind.

Wahrscheinlich ist es brk() Fragmentierungsproblem.

Also, was sind meine Optionen hier?

Sollte ich eine andere malloc() - Implementierung verwenden, die nur mmap() verwendet? Sollte ich etwas anderes machen? Kann ich etwas über das Problem mit dem Speicherabdruck lesen?

Danke.

Antwort

11

Wenn Ihr Programm so viele Aufrufe malloc und free hat, dass Sie diese Art von Fragmentierung erhalten, wird die Verwendung von mmap für jede Zuweisung hoffnungslos langsam sein. Stattdessen müssen Sie messen, was die Speicherfragmentierung verursacht und beheben. Zuerst würde ich ein Werkzeug wie Valgrind verwenden, um sicherzustellen, dass es sich nicht wirklich um ein Speicherleck-/Beschädigungsproblem handelt, das die übermäßige Speicherauslastung verursacht. Um zu bestätigen, dass die Fragmentierung die Ursache des Problems ist, würde ich alle Aufrufe an malloc und free mit einem eigenen Wrapper umwandeln, der eine "total allocated byte count" - Variable inkrementiert und dekrementiert, sodass Sie jederzeit die theoretischen und tatsächlicher Speicherverbrauch.

Wenn sich herausstellt, dass Fragmentierung das Problem ist, ist ein guter erster Schritt, warum Sie so viele kleine, kurzlebige Zuweisungen machen. Wenn Sie sie eliminieren können und stattdessen den gesamten Speicher, den ein bestimmtes Task/Datenobjekt in einem einzigen Block benötigt, zuweisen, zerhacken Sie es selbst. Sie werden nicht nur die schlimmste Fragmentierung beseitigen, sondern auch die Leistung Ihres Codes verbessern ein bisschen. Jeder Anruf bei malloc oder free verursacht einen hohen Overhead, insbesondere in einer Umgebung mit Threads, in der Synchronisierung/Sperrung erforderlich ist. Wenn alle zugehörigen Daten in einem einzigen zugewiesenen Block zusammengehalten werden, kann auch die Notwendigkeit verringert werden, speziellen Code in freie Strukturen zu schreiben, die Zeiger enthalten; Ein einzelner Aufruf an free kann oft ausreichen (aber um die Implementierung undurchsichtig zu halten, sollten Sie dies immer noch mit einer foo_free-Funktion umbrechen).

+1

Die Verwendung von 'mmap()' für jede Zuweisung wäre nicht nur langsam, sondern erhöht wahrscheinlich die Speichernutzung, da jede Zuweisung dann auf die Größe einer Speicherseite aufgerundet wird (mindestens 4k auf den meisten Plattformen). – alanc

+2

Grundsätzlich, wenn Sie eine Menge von identischen Allocs haben, rollen Sie Ihre eigene Freelist und reservieren Sie eine Tonne von Blöcken vor.Sie können hier eine nette, lockfreie Freelist finden; http://www.liblfds.org (Interessensbekundung: Ich bin der Autor). Ich habe gerade einen Benchmark dieser Freelist gegen eine Mutex-Freelist gemacht; es ist 10x schneller auf einem Kern, 100x schneller auf zwei! –

+0

Danke. Es ist definitiv nicht undicht. Ich werde weiter untersuchen. –

2

Wenn Sie keine Blöcke mit fester Größe zuweisen oder eine periodische Speicherbereinigung durchführen, wird Ihr Speicherbedarf aufgrund der Fragmentierung wahrscheinlich über das hinausgehen, was erforderlich ist.

free() können Speicher nur dann zum Betriebssystem zurückgeben, wenn ganze Seiten nicht verwendet werden.

Mein Vorschlag wäre, ein slab allocation Schema zu verwenden. Teilen Sie mehrere Speicherpools vorab zu. Jeder Pool wird mit Objekten ähnlicher Größe (idealerweise identische Größe) verwendet. Auf diese Weise vermeiden Sie eine Fragmentierung und halten Ihren RSS-Footprint konstant (wenn auch größer als unbedingt erforderlich aufgrund der Vorbelegung).

Verwandte Themen