Frage

Hintergrund: Ich bin ein C ++ Programm arbeitet mit großen Mengen von Geodaten zu schreiben und will große Teile laden in einem Rutsch zu verarbeiten. Ich bin gezwungen mit einer App zu arbeiten für 32-Bit-Maschinen zusammengestellt. Die Maschine, die ich testen bin auf ist ein 64-Bit-Betriebssystem (Windows 7) und 6 GB RAM. Mit MS VS 2008.

Ich habe den folgenden Code:

byte* pTempBuffer2[3];
try
{
    //size_t nBufSize = nBandBytes*m_nBandCount;
    pTempBuffer2[0] = new byte[nBandBytes];
    pTempBuffer2[1] = new byte[nBandBytes];
    pTempBuffer2[2] = new byte[nBandBytes];
}
catch (std::bad_alloc)
{
    // If we didn't get the memory just don't buffer and we will get data one
    // piece at a time.
    return;
}

Ich habe gehofft, dass ich Speicher zuzuweisen wäre in der Lage, bis der App, die 4-Gigabyte-Grenze von 32-Bit-Adressierung erreicht. Wenn jedoch nBandBytes ist 466.560.000 die neue wirft std :: bad_alloc beim zweiten Versuch. In diesem Stadium der Arbeitssatz (Speicher) Wert für den Prozess ist 665.232 K Also, es mir noch einen Gig von Speichern zugewiesen bekommt nicht in die Lage zu sein scheint.

Es hat sich für den Einsatz in 32-Bit-Windows-einige Erwähnung einer 2 Gig Grenze gewesen, die mit dem / 3GB für win32 bis 3 Gig kann verlängert werden. Dies ist ein guter Rat unter dieser Umgebung, aber nicht relevant für diesen Fall.

Wie viel Speicher sollten Sie in der Lage sein, unter der 64-Bit-Betriebssystem mit einem 32-Bit-Anwendung zuordnen?

War es hilfreich?

Lösung

So viel wie das O will dir geben. Standardmäßig läßt Windows-32-Bit-Prozess 2 GB Adressraum hat. Und das ist in mehrere Stücke aufgeteilt. Ein Bereich wird beiseite gestellt für den Stapel, die anderen für jede ausführbare und DLL, die geladen wird. Was auch immer kann gelassen werden dynamisch zugewiesen, aber es gibt keine Garantie, dass es dann einen großen zusammenhängenden Brocken sein. Es könnte jeweils mehrere kleinere Brocken von ein paar hundert MB groß sein.

Wenn Sie mit dem LARGEADDRESSAWARE Flag kompilieren, 64-Bit-Windows lässt Dich verwenden, um den vollen 4 GB Adressraum, der ein bisschen helfen soll, aber im Allgemeinen,

  • Sie sollten nicht davon ausgehen, dass die zur Verfügung stehenden Speicher angrenzt. Sie sollten statt wenige große mit mehreren kleineren Zuweisungen in der Lage zu arbeiten, und
  • Sie sollten es als 64-Bit-Anwendung kompilieren, wenn Sie viel Speicher benötigen.

Andere Tipps

auf Windows 32 Bit, der normale Prozess 2 GB maximal nehmen, aber mit

Sie können so viel Speicher wie Sie Ihre Auslagerungsdatei vergeben werden Sie lassen - auch ohne die Option / 3GB, Sie 4 GB Speicher kann ohne große Schwierigkeiten zuordnen kann.

Lesen dieser Artikel für einen guten Überblick darüber, wie über physische Speicher, virtuellen Speicher zu denken, und Adressraum (alle drei sind verschiedene Dinge). Auf dem Punkt gebracht, haben Sie genau so viele physischen Speicher, wie Sie RAM haben, aber Ihre App hat wirklich keine Interaktion mit dem physischen Speicher überhaupt - es ist nur ein bequemer Platz, um die Daten zu speichern, die in der virtuellen Speicher. Ihr virtueller Speicher wird durch die Größe der Auslagerungsdatei begrenzt, und die Menge der App verwenden kann, ist dadurch begrenzt, wie viele andere Apps verwenden (obwohl Sie mehr zuordnen können, vorausgesetzt, Sie haben es tatsächlich nicht verwendet werden). Ihr Adressraum in der 32-Bit-Welt ist 4 GB. Davon sind 2 GB für den Kernel zugeordnet (oder 1 GB, wenn Sie die / 3BG Schalter verwenden). Von dem 2 GB, die noch übrig ist, wird ein Teil von Ihrem Stapel geht ausgenutzt werden, einige durch das Programm laufen Sie zur Zeit, (und alle DLLs, etc ..). Es wird fragmentiert, und Sie sind nur so viel zusammenhängenden Raum gehen zu können, bekommen - das ist, wo Ihre Zuteilung ausfällt. Aber da das Adressraum ist nur eine bequeme Möglichkeit, den virtuellen Speicher zugreifen, die Sie für Sie vergeben haben, ist es möglich, viel mehr Speicher zuzuweisen, und bringen Brocken in Ihren Adressraum ein paar zu einer Zeit.

Raymond Chen hat ein Beispiel dafür, wie 4 GB Speicher und Karten Teil davon in einen Abschnitt Ihrer Adressraum zuzuordnen.

Unter 32-Bit-Windows, die maximalen zuweisbaren ist 16TB und 256 TB in 64-Bit-Windows-.

Und wenn Sie wirklich in sind, wie Speicherverwaltung funktioniert in Windows, lesen Sie dieser Artikel .

Während des ElephantsDream Projekt der Blender Foundation mit Blender 3D ähnliche Probleme hatte (wenn auch auf dem Mac). Kann nicht die Verbindung schließen ein, aber google. Blender3D Speicherzuweisung Problem, und es wird das erste Element sein

Die Lösung beteiligt File Mapping. Habe es selbst nicht ausprobiert, aber man kann hier auf es nachlesen:

Mit nBandBytes bei 466.560.000, Sie versuchen, 1,4 GB zuweisen. Ein 32-Bit-App hat in der Regel nur den Zugriff auf 2 GB Arbeitsspeicher (mehr, wenn Sie mit / 3GB booten und die ausführbare Datei als große Adressraum bewusst markiert). Sie können sich schwer tun werden, dass viele Blöcke von zusammenhängenden Adressraum für Ihre große Teile des Speichers zu finden.

Wenn Sie auf einem 64-Bit-OS Gigabyte Speicher zuzuweisen, verwenden Sie ein 64-Bit-Prozess.

Es soll möglich sein, insgesamt etwa 2 GB pro Prozess zuzuordnen. Dieser Artikel (PDF) erklärt die Details. Jedoch nicht in der Lage sein, das Sie wahrscheinlich einen einzigen, zusammenhängenden Block zu erhalten, die zu diesem großen sogar in der Nähe ist.

Auch wenn Sie in kleinere Stücke zuordnen, können Sie den Speicher nicht erhalten Sie brauchen, vor allem, wenn das umgebende Programm unberechenbar Speicherverhalten hat, oder wenn Sie auf verschiedenen Betriebssystemen ausgeführt werden müssen. Nach meiner Erfahrung, Kappen der Heap-Speicher auf einem 32-Bit-Prozess bei etwa 1,2 GB.

Bei dieser Menge an Speicher, würde ich manuell auf die Festplatte zu schreiben empfehlen. Wickeln Sie Ihre Arrays in einer Klasse, die den Speicher und schreibt temporäre Dateien bei Bedarf verwaltet. Hoffentlich werden die Eigenschaften des Programms sind so, dass Sie effektiv Teile dieser Daten zwischenspeichern konnte die Scheibe zu viel, ohne auf.

Sysinternals VMMap virtuellen zur Untersuchung von Adressraum Fragmentierung groß ist, was wahrscheinlich ist, zu begrenzen, wie viel zusammenhängende Speicher Sie zuordnen können. Ich empfehlen, es freien Speicherplatz anzuzeigen, und dann nach Größe Sortieren der größten freien Bereiche zu finden, die dann nach Adressen Sortierung zu sehen, was die größten freien Flächen trennt (wahrscheinlich umbasiert DLLs, gemeinsame Speicherbereiche oder andere Halden).

Die Vermeidung extrem große zusammenhängende Zuweisungen ist wahrscheinlich das Beste, wie andere vorgeschlagen haben.

LARGE_ADDRESS_AWARE=YES Einstellung (wie JALF vorgeschlagen) ist gut, solange die Bibliotheken, die Ihre Anwendung mit ihm kompatibel sind, hängt davon ab. Wenn Sie dies tun, sollten Sie Ihren Code mit dem AllocationPreference Registrierungsschlüssel-set-Top-down virtuelle Adresszuordnung zu ermöglichen.

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