Ich arbeite gerade mit sehr großen Datensätzen über 2,5 GB Speicher.
Ich speichere dies derzeit, indem ich einen Vektor der Klasse Data, die enthält, verwende
1) Metadaten
2) boost::ptr_list<MemoryBlock>
Die MemoryBlock-Klasse enthält
1) Metadaten
2) std::vector<XYZ>
Beim Auffüllen reserviere ich meine std::vector<xyz>
in Gruppen von 50.000. Wenn die räumlichen Dimensionen meines Vektors zu groß werden, werde ich einen neuen Speicherblock erstellen und verwenden
std::vector<XYZ>(Points).swap(Points)
, um den Vektor auf die richtige Größe zu verkleinern.
Jetzt das Problem ... Es scheint, dass ich, wenn ich den Swap-Trick benutze, um die Größe meines Arrays zu ändern, nach dem Löschen aller meiner Daten und dem Laden eines neuen Datensatzes in std :: bad_alloc-Exceptions stolpere.
Die Menge an Daten, die ich einlesen kann, schrumpft drastisch ... Es wird dies auch jedes Mal tun, wenn ich meine Daten lösche und einen neuen Datensatz einlege ... Zum Beispiel: Mein ursprünglicher Datensatz wird in 100.000.000 geladen Werte
nächstes Mal wird es 70.000.000 Werte laden
Nächstes Mal 50.000.000 Werte
nächstes Mal 20.000.000 Werte usw. ...
Mein erster Gedanke ist ein Speicherleck, aber es gibt nichts, was ich identifizieren konnte. Alles im Code mit Ausnahme des Swaps wurde lange Zeit ohne Probleme verwendet.
Wenn ich die Überprüfung der Swap- / räumlichen Dimensionen nicht verwende, läuft alles weiter und funktioniert ordnungsgemäß.
irgendwelche Ideen?!?
Bearbeiten
%Vor%Hier ist das Code-Segment, das dies verwendet.
%Vor% Diese Technik scheint die Fragmentierung zu garantieren, wenn Sie zwischen Check_MemBlock_Size()
etwas mehr dynamische Zuweisung vornehmen. Das liegt daran, dass Sie Ihre 50K-Zuweisung freigeben, nachdem Sie Ihren kleineren Chunk zugewiesen haben, indem Sie ein 50K-Objekt-Loch im Speicher erstellen, das jetzt teilweise durch etwas mehr Speicher gefüllt werden kann, den Ihre nächste Neuerstellung von MemoryBlock
nicht verwenden kann.
Sie könnten einen globalen Vektor anstelle eines temporären erstellen, um diese 50K-Objektzuordnung zu halten. Wenn Sie dann als Nächstes einen neuen MemoryBlock
neu erstellen, müssen Sie anstelle eines neuen 50K-Objektvektors einfach den globalen ersetzen. Wenn du es verkleinern willst, tausche es wieder mit dem globalen aus. Wenn Sie den reservierten 50K-Speicher auf diese Weise wiederverwenden, wird jede Fragmentierung entfernt, zu der diese Zuordnung beigetragen haben könnte.
Es gibt jedoch möglicherweise andere Quellen für die Fragmentierung in Ihrem Programm, wenn Sie sicher sind, dass keine Lecks vorhanden sind. In der Regel wird die Fragmentierung durch eine Mischung aus großen und kleinen Objekten verursacht, die dynamisch zugeordnet sind und jeweils unterschiedliche Lebensdauern aufweisen. Es gibt viele Möglichkeiten, es zu lösen, aber eine Möglichkeit, um damit umzugehen, ist mit Speicherpools. Ein Pool in diesem Sinne ist eine Sammlung von Objekten gleicher Größe und gleicher Lebensdauer, die in einem benutzerdefinierten Zuordner gruppiert sind. Die Freigabe eines solchen Speichers wird zu seinem Pool zurückgegeben. Wenn der Speicher niemals mit delete
an das System zurückgegeben wird, wirkt der Pool der Fragmentierung entgegen, indem zukünftige Zuweisungen die Wiederverwendung von Speicher zulassen, der zuvor für denselben Objekttyp reserviert wurde. Die Pools wachsen mit der maximalen Laufzeitauslastung und die Fragmentierung ist niemals schlimmer als diese.
Tags und Links c++