OK, also, ich schrieb einen Code, um zu überprüfen, wie viel Speicher zur Laufzeit verfügbar ist. Eine ganze (minimale) CPP-Datei ist darunter.neu und löschen [] sind schlechter als malloc und frei? (C++/VS2012)
HINWEIS: Der Code ist nicht perfekt und nicht Best Practice, aber ich hoffe, dass Sie sich auf das Speichermanagement und nicht auf den Code konzentrieren können.
Was sie tut (Teil I):
- (1) Ordnen Sie so viel Speicher wie möglich in einem Block. Löschen Sie diesen Speicher
- (2) Reservieren Sie so viele mittelgroße Blöcke (16MB) wie möglich. Löschen Sie diese Erinnerung.
-> Dies funktioniert
Was sie tut (Teil II):
- (1) in einem Block so viel Speicher wie möglich zuzuteilen. Löschen Sie diesen Speicher
- (2) Zuordnen Sie so viele winzige Blöcke (16 KB) wie möglich. Löschen Sie diese Erinnerung.
-> Dies verhält sich komisch!
Das Problem ist: Wenn ich das wiederhole, kann ich nur 522kb für die secons vergeben weiterlaufen --->?
Es passiert nicht, wenn die zugewiesenen Blöcke z. 16 MB Größe.
Haben Sie irgendwelche Ideen, warum das passiert?
// AvailableMemoryTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <vector>
#include <list>
#include <limits.h>
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
auto determineMaxAvailableMemoryBlock = [](void) -> int
{
int nBytes = std::numeric_limits<int>::max();
while (true)
{
try
{
std::vector<char>vec(nBytes);
break;
}
catch (std::exception& ex)
{
nBytes = static_cast<int>(nBytes * 0.99);
}
}
return nBytes;
};
auto determineMaxAvailableMemoryFragmented = [](int nBlockSize) -> int
{
int nBytes = 0;
std::list< std::vector<char> > listBlocks;
while (true)
{
try
{
listBlocks.push_back(std::vector<char>(nBlockSize));
nBytes += nBlockSize;
}
catch (std::exception& ex)
{
break;
}
}
return nBytes;
};
std::cout << "Test with large memory blocks (16MB):\n";
for (int k = 0; k < 5; k++)
{
std::cout << "run #" << k << " max mem block = " << determineMaxAvailableMemoryBlock()/1024.0/1024.0 << "MB\n";
std::cout << "run #" << k << " frag mem blocks of 16MB = " << determineMaxAvailableMemoryFragmented(16*1024*1024)/1024.0/1024.0 << "MB\n";
std::cout << "\n";
} // for_k
std::cout << "Test with small memory blocks (16k):\n";
for (int k = 0; k < 5; k++)
{
std::cout << "run #" << k << " max mem block = " << determineMaxAvailableMemoryBlock()/1024.0/1024.0 << "MB\n";
std::cout << "run #" << k << " frag mem blocks of 16k = " << determineMaxAvailableMemoryFragmented(16*1024)/1024.0/1024.0 << "MB\n";
std::cout << "\n";
} // for_k
std::cin.get();
return 0;
}
OUTPUT mit großen Speicherblöcke (das funktioniert gut)
Test with large memory blocks (16MB):
run #0 max mem block = 1023.67MB OK
run #0 frag mem blocks of 16MB = 1952MB OK
run #1 max mem block = 1023.67MB OK
run #1 frag mem blocks of 16MB = 1952MB OK
run #2 max mem block = 1023.67MB OK
run #2 frag mem blocks of 16MB = 1952MB OK
run #3 max mem block = 1023.67MB OK
run #3 frag mem blocks of 16MB = 1952MB OK
run #4 max mem block = 1023.67MB OK
run #4 frag mem blocks of 16MB = 1952MB OK
OUTPUT mit kleinen Speicherblöcke (Speicherzuweisung ist aus dem zweiten Lauf ab seltsam)
Test with small memory blocks (16k):
run #0 max mem block = 1023.67MB OK
run #0 frag mem blocks of 16k = 1991.06MB OK
run #1 max mem block = 0.493021MB ???
run #1 frag mem blocks of 16k = 1991.34MB OK
run #2 max mem block = 0.493021MB ???
run #2 frag mem blocks of 16k = 1991.33MB OK
run #3 max mem block = 0.493021MB ???
run #3 frag mem blocks of 16k = 1991.33MB OK
run #4 max mem block = 0.493021MB ???
run #4 frag mem blocks of 16k = 1991.33MB OK
UPDATE:
Dies passiert auch mit Neu und lösche [] anstelle der internen Speicherzuweisung von STL.
UPDATE:
Es funktioniert für 64-Bit (I begrenzt den Speicher, der beide Funktionen erlaubt sind 12GB zuzuteilen). Sehr seltsam. Hier ist ein Bild dieser RAM-Nutzung Version:
UPDATE: Es arbeitet mit malloc und frei, aber nicht mit neuen und löschen [] (oder STL wie oben beschrieben)
Eine Möglichkeit: Heap-Manager neigen dazu, verschiedene Abschnitte des Heaps für verschiedene Blockgrößen zu haben. Es kann sein, dass wenn Sie zuerst alles mit kleinen Blöcken füllen, einer der kleinen Block-Heap-Bereiche alles übernimmt, wie es für zukünftige Allokationen übrig bleibt. –
OK, aber warum speichert es den Speicher, anstatt ihm die nächste Zuweisung zu geben? Es wird nicht mehr verwendet ... –
Warum erstellen Sie 'std :: vector' anstelle der direkteren Methoden ('new char []' oder 'malloc')? –
sfstewman