Wie viel Speicher sollten Sie zuweisen können?

7

Hintergrund: Ich schreibe ein C ++ - Programm, das mit großen Mengen von Geodaten arbeitet und große Stücke laden möchte, um sie auf einmal zu verarbeiten. Ich bin gezwungen, mit einer App zu arbeiten, die für 32-Bit-Maschinen kompiliert wurde. Der Rechner, auf dem ich teste, läuft mit einem 64-Bit-Betriebssystem (Windows 7) und hat 6 GB RAM. Verwenden von MS VS 2008.

Ich habe den folgenden Code:

%Vor%

Ich hatte gehofft, dass ich Speicher zuordnen könnte, bis die App die 4-Gigabyte-Grenze der 32-Bit-Adressierung erreicht hat. Wenn nBandBytes jedoch 466.560.000 ist, löst das neue std :: bad_alloc beim zweiten Versuch aus. In diesem Stadium ist der Arbeitssatz (Speicher) -Wert für den Prozess 665.232 K. Es scheint mir nicht möglich zu sein, sogar einen Gig Speicher zuzuordnen.

Es wurde ein Limit von 2 Gigs für Anwendungen in 32-Bit-Windows erwähnt, das mit dem / 3GB-Switch für win32 auf 3 Gigs erweitert werden kann. Dies ist ein guter Rat in dieser Umgebung, aber nicht relevant für diesen Fall.

Wie viel Speicher sollten Sie unter dem 64-Bit-Betriebssystem mit einer 32-Bit-Anwendung zuweisen können?

    
Bill 23.06.2009, 17:39
quelle

8 Antworten

10

So viel wie das OS Ihnen geben will. Standardmäßig lässt Windows einem 32-Bit-Prozess 2 GB Adressraum. Und das ist in mehrere Stücke aufgeteilt. Ein Bereich ist für den Stack reserviert, andere für jede ausführbare Datei und DLL, die geladen wird. Was noch übrig ist, kann dynamisch zugewiesen werden, aber es gibt keine Garantie, dass es ein großer zusammenhängender Chunk ist. Es könnten mehrere kleinere Stücke von jeweils ein paar hundert MB sein.

Wenn Sie mit dem LargeAddressAware-Flag kompilieren, können Sie mit 64-Bit-Windows den vollen 4-GB-Adressraum verwenden, was ein wenig helfen sollte, aber im Allgemeinen

  • Sie sollten nicht davon ausgehen, dass der verfügbare Speicher zusammenhängend ist. Sie sollten in der Lage sein, mit mehreren kleineren Zuordnungen statt mit ein paar großen zu arbeiten, und
  • Sie sollten es als 64-Bit-Anwendung kompilieren, wenn Sie viel Speicher benötigen.
jalf 23.06.2009, 17:48
quelle
6

unter Windows 32 bit, der normale Prozess kann maximal 2 GB dauern, aber mit / 3GB Schalter kann bis zu 3 GB erreichen (für Windows 2003).

aber in Ihrem Fall denke ich, dass Sie zusammenhängenden Speicher zuweisen, und so ist die Ausnahme aufgetreten.

    
Ahmed Said 23.06.2009 17:45
quelle
4

Sie können so viel Speicher reservieren, wie Ihre Seitendatei Ihnen erlauben wird - selbst ohne den Schalter / 3GB können Sie 4 GB Speicher ohne große Schwierigkeiten zuweisen.

Lesen Dieser Artikel bietet einen guten Überblick darüber, wie man über physischen Speicher, virtuellen Speicher und Adressraum denkt (alle drei sind unterschiedliche Dinge). Kurz gesagt, Sie haben genau so viel physischen Speicher wie Sie RAM haben, aber Ihre App hat wirklich keine Interaktion mit diesem physischen Speicher - es ist nur ein praktischer Ort, um die Daten in Ihrem virtuellen Speicher zu speichern. Ihr virtueller Speicher ist durch die Größe Ihrer Auslagerungsdatei begrenzt, und die Menge, die Ihre App verwenden kann, ist davon abhängig, wie viele andere Apps verwendet werden (obwohl Sie mehr zuweisen können, sofern Sie sie nicht tatsächlich verwenden). Ihr Adressraum in der 32-Bit-Welt ist 4 GB. Davon werden 2 GB dem Kernel zugewiesen (oder 1 GB, wenn Sie den Schalter / 3BG verwenden). Von den verbleibenden 2 GB werden einige von Ihrem Stack verbraucht, einige von dem Programm, das Sie gerade ausführen (und alle DLLs, etc ..). Es wird fragmentiert, und Sie werden nur in der Lage sein, so viel zusammenhängenden Platz zu bekommen - hier schlägt Ihre Zuteilung fehl. Aber da dieser Adressraum nur eine bequeme Möglichkeit ist, auf den virtuellen Speicher zuzugreifen, den Sie für sich reserviert haben, ist es möglich, viel mehr Speicher zuzuweisen und einige davon gleichzeitig in Ihren Adressraum zu bringen.

Raymond Chen hat ein Beispiel zur Zuweisung von 4 GB Speicher und Teilen Sie einen Teil davon in einen Abschnitt Ihres Adressraums ein.

Unter 32-Bit-Windows ist der maximal zuweisbare Wert 16 TB und 256 TB in 64-Bit-Windows.

Und wenn Sie wirklich wissen möchten, wie die Speicherverwaltung in Windows funktioniert, lesen Sie diesen Artikel .

    
Eclipse 23.06.2009 18:05
quelle
2

Während des ElephantsDream-Projekts hatte die Blender Foundation mit Blender 3D ähnliche Probleme (allerdings auf Mac). Kann nicht den Link aber google: blender3d Speicherzuweisung Problem enthalten und es wird das erste Element sein.

Die Lösung beinhaltete die Dateizuordnung. Habe es nicht selbst ausprobiert, aber du kannst es hier nachlesen: Ссылка

    
tombjo 23.06.2009 18:07
quelle
1

Mit nBandBytes bei 466.560.000 versuchen Sie, 1,4 GB zuzuweisen. Eine 32-Bit-App hat normalerweise nur Zugriff auf 2 GB Arbeitsspeicher (mehr, wenn Sie mit / 3 GB booten und die ausführbare Datei als großer Adressraum gekennzeichnet ist). Es kann sein, dass Sie Schwierigkeiten haben, viele Blöcke zusammenhängender Adressräume für Ihre großen Speicherbereiche zu finden.

Wenn Sie auf einem 64-Bit-Betriebssystem Gigabyte Speicher reservieren möchten, verwenden Sie einen 64-Bit-Prozess.

    
Michael 23.06.2009 17:49
quelle
1

Sie sollten insgesamt etwa 2 GB pro Prozess zuweisen können. Dieser Artikel (PDF) erklärt die Details. Es ist jedoch wahrscheinlich nicht möglich, einen einzelnen, zusammenhängenden Block zu erhalten, der diesem Wert sehr nahe kommt.

    
Naaff 23.06.2009 17:51
quelle
1

Selbst wenn Sie kleinere Blöcke zuweisen, konnten Sie nicht den benötigten Speicher abrufen, insbesondere wenn das umgebende Programm unvorhersehbares Speicherverhalten aufweist oder wenn Sie auf verschiedenen Betriebssystemen ausgeführt werden müssen. Meiner Erfahrung nach liegt der Heap-Speicher eines 32-Bit-Prozesses bei etwa 1,2 GB.

Bei dieser Speichermenge würde ich empfehlen, manuell auf die Festplatte zu schreiben. Wickeln Sie Ihre Arrays in eine Klasse ein, die den Speicher verwaltet und bei Bedarf in temporäre Dateien schreibt. Hoffentlich sind die Eigenschaften Ihres Programms so, dass Sie Teile dieser Daten effektiv cachen können, ohne die Festplatte zu sehr zu treffen.

    
Drew Hoskins 23.06.2009 18:03
quelle
1

Sysinternals VMMap eignet sich hervorragend für die Untersuchung der Fragmentierung virtueller Adressräume, die wahrscheinlich die Zugriffsgeschwindigkeit begrenzt zusammenhängender Speicher, den Sie zuweisen können. Ich empfehle, den freien Speicherplatz anzuzeigen, dann nach Größe zu sortieren, um die größten freien Bereiche zu finden, und dann nach Adresse zu sortieren, um zu sehen, was die größten freien Bereiche trennt (wahrscheinlich rebased DLLs, shared memory regions oder andere Heaps).

Das Vermeiden extrem großer zusammenhängender Zuordnungen ist wahrscheinlich das Beste, wie andere vorgeschlagen haben.

Das Festlegen von LARGE_ADDRESS_AWARE=YES (wie von jalf vorgeschlagen) ist gut, solange die Bibliotheken, von denen Ihre Anwendung abhängt, damit kompatibel sind. Wenn Sie dies tun, sollten Sie Ihren Code mit dem AllocationPreference testen Registrierungsschlüssel festgelegt, um Top-Down-Zuweisung virtueller Adressen zu ermöglichen.

    
bk1e 23.06.2009 18:23
quelle