OK, also habe ich Code geschrieben, um zu überprüfen, wie viel Speicher zur Laufzeit verfügbar ist. Eine ganze (minimale) CPP-Datei ist unter.
HINWEIS: Der Code ist nicht perfekt und nicht die beste Vorgehensweise, aber ich hoffe, dass Sie sich auf die Speicherverwaltung und nicht auf den Code konzentrieren können.
Was es tut (Teil I):
- & gt; Das funktioniert gut
Was es tut (Teil II):
- & gt; Das verhält sich komisch!
Das Problem ist: Wenn ich das wiederhole, kann ich nur 522kb für die laufenden secons zuweisen --- & gt; ?
Es passiert nicht, wenn die zugewiesenen Blöcke z. 16 MB Größe.
Haben Sie irgendwelche Ideen, warum das passiert?
%Vor%OUTPUT mit großen Speicherblöcken (das funktioniert gut)
%Vor%OUTPUT mit kleinen Speicherblöcken (die Speicherzuweisung ist ab dem zweiten Lauf seltsam)
%Vor%UPDATE:
Dies passiert auch mit neuen und lösch [] anstelle der internen Speicherzuweisung von STL.
UPDATE:
Es funktioniert für 64 Bit (ich habe den Speicher begrenzt, den beide Funktionen zu 12GB zuweisen können). Sehr seltsam. Hier ist ein Bild der RAM-Nutzung dieser Version:
UPDATE: Es funktioniert mit malloc und free, aber nicht mit new und delete [] (oder STL wie oben beschrieben)
Wie ich bereits im obigen Kommentar erwähnt habe, handelt es sich höchstwahrscheinlich um ein Heap-Problem Fragmentierung . Der Heap verwaltet Listen von Blöcken unterschiedlicher Größe, um unterschiedliche Speicheranforderungen zu erfüllen. Größere Speicherblöcke werden für kleinere Speicheranfragen in kleinere Blöcke aufgeteilt, um zu vermeiden, dass der Unterschied zwischen der Chunk-Größe und der Anforderungsgröße verschwendet wird, was die Anzahl größerer Chunks reduziert. Wenn also ein größerer Chunk angefordert wird, verfügt der Heap möglicherweise nicht über genügend große Chunks, um die Anforderung zu erfüllen.
Fragmentierung ist ein Hauptproblem bei Heap-Implementierungen, da sie den nutzbaren Speicher effektiv reduziert. Einige Heap-Implementierungen können jedoch kleinere Chunks wieder in größere Chunks zusammenfügen und sind in der Lage, auch nach einer Anzahl kleinerer Anfragen größere Anforderungen zu erfüllen.
Ich habe Ihren obigen Code, sehr leicht modifiziert, mit% malloc
( ptmalloc
) von glibc ausgeführt und ich habe die folgenden Ergebnisse erhalten ...
Also scheint ptmalloc
zumindest die Fragmentierung gut für dieses spezielle Szenario zu handhaben.
Ich vermute, dass Sie aus irgendeinem Grund 32-Bit-Code ausführen?
Beste Schätzung: Ihre malloc
-Implementierung hinterlässt Buchhaltungsdaten nach dem Freigeben überall im Speicher verstreut, wenn die Zuweisungen klein waren. Malloc-Implementierungen verwenden in der Regel unterschiedliche Zuweisungsstrategien für kleine und große Zuweisungen, so dass es nicht unangemessen ist, dass sich die Buchhaltungsinformationen an verschiedenen Stellen befinden.
Unter Unix werden kleine Zuweisungen normalerweise mit brk
durchgeführt, während große Zuweisungen mit mmap(MAP_ANONYMOUS)
erledigt werden. _tmain
und stdafx.h
bedeutet, dass Sie unter Windows testen, also IDK, wie dieses malloc unter der Haube funktioniert.
Tags und Links memory c++ memory-management