Frage

Ich möchte eine Datei in den Speicher abzubilden Mmap Funktion und würde gerne wissen, ob die Größe des virtuellen Speichers auf der aktuellen Plattform ausreichend ist, eine riesige Datei abzubilden. Für ein 32-System kann ich nicht Datei größer als 4 GB Karte.
Würde std::numeric_limits<size_t>::max() geben Sie mir die Menge an Speicher oder gibt es eine andere Art, dass ich testen sollte (off_t oder etwas anderes)?

Wie Lie Ryan hat in seinem Kommentar die „virtual memory“ hier darauf hingewiesen, missbraucht wird. Die Frage, hält jedoch: Es gibt einen Typ mit einem Zeiger zugeordnet ist, und es hat den Maximalwert, der die obere Grenze dessen, was definiert Sie können möglicherweise auf Ihrem System-Adresse. Was ist diese Art? Ist es size_t oder vielleicht ptrdiff_t?

War es hilfreich?

Lösung

size_t ist nur erforderlich, groß genug, um ein möglichst großes einziges zusammenhängendes Objekt zu speichern. Das kann nicht das gleiche sein wie die Größe des Adressraumes (auf Systeme mit einem segmentierten Speichermodell, zum Beispiel)

jedoch auf gemeinsame Plattformen mit einem flachen Speicherplatz, sind die beide gleich, und so können Sie mit der Verwendung von size_t in der Praxis wegkommen können, wenn Sie den Ziel-CPU kennen.

Wie auch immer, bedeutet dies nicht wirklich sagen Sie etwas Nützliches. Sicher, ein 32-Bit-CPU hat einen 4 GB Speicherplatz, und so size_t ist eine 32-bit unsignierte Ganzzahl. Aber das sagt nichts darüber, wie viel Sie zuordnen können. Ein Teil des Speicherplatzes wird durch das OS verwendet. Und einige Teile bereits von Ihrer eigenen Anwendung verwendet. Zur Abbildung der ausführbaren in den Speicher (sowie alle dynamischen Bibliotheken es verwenden kann), für jeden Stapel des Threads, reservierte Speicher auf dem Heap und so weiter

Also nein, Tricks wie die Größe der size_t Einnahme sagt Ihnen ein wenig über den Adressraum Sie laufen in, aber nichts sehr brauchbar. Sie können die OS fragen, wie viel Speicher im Gebrauch durch Ihren Prozess und anderen Metriken ist, aber auch hier, dass nicht wirklich Sie viel helfen. Es ist möglich, dass ein Prozess nur ein paar Megabyte zu verwenden, aber haben diese verteilt über so viele kleine Zuteilungen, dass sie einen zusammenhängenden Speicherblock zu finden größer als 100 MB, sagen unmöglich ist. Und so, auf einem 32-Bit-Maschine, mit einem Prozess, der fast keinen Speicher verwendet, dann würden Sie wahrscheinlich nicht, eine solche Zuordnung zu machen. (Und selbst wenn das Betriebssystem eine magische WhatIsTheLargestPossibleMemoryAllocationICanMake() API hatte, dass noch Sie würde nicht helfen. Es würde Ihnen sagen, was man brauchte von vor einem Augenblick . Sie haben keine Garantie, dass die Antwort immer noch gültig, bis Sie versuchte, würde die Datei zu kartieren.

Also wirklich, das Beste, was Sie tun können, ist versuchen , um die Datei auf der Karte, und sehen, ob es funktioniert nicht.

Andere Tipps

Hallo können Sie GlobalMemoryStatusEx und VirtualQueryEx verwenden, wenn Sie bei der Codierung win32

Das Ding ist, die Größe eines Zeigers sagt nichts darüber, wie viel von diesem „Adressraum“ steht Sie tatsächlich zur Verfügung steht, kann das heißt als eine einzige zusammenhängende Chunk zugeordnet werden.

Es ist begrenzt durch:

  • das Betriebssystem. Es kann nur eine Teilmenge des theoretisch möglichen Adressbereiches zur Verfügung stellen, weil mappable Speicher für OS-eigene Zwecke benötigt wird (wie, sagen sie, Framebuffer sichtbar die Grafikkarte zu machen, und natürlich auch für die Verwendung durch das Betriebssystem selbst ).
  • konfigurierbaren Grenzen. Unter Linux / UNIX, der "ulimit" Befehl resp. setrlimit () Systemaufruf ermöglicht die maximale Größe einer Anwendung Adressraum auf verschiedene Weise zu beschränken, und Windows hat ähnliche Optionen durch Registrierungsparameter.
  • die Geschichte der Anwendung. Wenn die Anwendung Speicherzuordnung ausgiebig verwendet, kann der Adressraum fragmentieren die maximale Größe von „verfügbar“ zusammenhängenden virtuellen Adressen zu begrenzen.
  • die Hardware-Plattform. Einige CPUs haben Adressräume mit „Löchern“; ein Beispiel dafür ist 64-Bit-x86 wo Zeiger nur dann gültig sind, wenn sie zwischen 0x0..0x7fffffffffff oder 0xffff000000000000 und 0xFFFFFFFFFFFFFFFF sind. D. h Sie haben 2x128TB anstelle des vollständigen 16EB. Betrachten Sie es als 48-Bit "unterzeichnet" Zeiger ...

Schließlich nicht zu verwechseln „verfügbare Speicher“ und „verfügbaren Adressraum“. Es gibt einen Unterschied zwischen einem malloc tun (someBigSize) und mmap (..., someBigSize, ...), weil die frühere Verfügbarkeit von physischen Speicher benötigen könnte die Anforderung zu erfüllen, während letztere in der Regel nur die Verfügbarkeit eines groß genug frei erfordert Adressbereich.

Für UNIX-Plattformen, einen Teil der Antwort ist die Verwendung getrlimit (RLIMIT_AS), da dies die für den aktuellen Aufruf der Anwendung Obergrenze gibt - wie gesagt, den Benutzer und / oder Administrator kann diese konfigurieren. Sie garantiert, dass jeder Versuch Bereich mmap größer als die fehlschlagen.

Re Ihre umformuliert Frage „Obergrenze dessen, was Sie können möglicherweise Adresse auf Ihrem System“ ist etwas irreführend; es ist Hardware-Architektur spezifisch. Es gibt 64-Bit-Architekturen gibt (x64, Sparc), deren MMU erlaubt glücklich (uintptr_t) (- 1) als gültige Adresse, das heißt Sie etwas in die letzte Seite eines 64-Bit-Adressraum zuordnen. Ob das Betriebssystem eine Anwendung ermöglicht es so oder nicht zu tun, ist wieder eine ganz andere Frage ...

Für Benutzeranwendungen, die „hohe Marke“ nicht (immer) fixiert a-priori. Es ist abstimmbar auf z.B. Solaris oder Linux. Das ist, wo getrlimit (RLIMIT_AS) kommt in.

Beachten Sie, dass wieder, durch die Angabe, es gibt nichts würde ein (komisch) Betriebssystem-Design zu verhindern, zum Beispiel zu wählen Putting Anwendung Stapel und Anhäufungen auf „low“, während Adressen-Code auf „high“ Adressen setzen, auf einer Plattform mit Adreßraum Löchern. Sie würden es volle 64-Bit-Zeiger, dann können sie nicht noch kleiner machen, aber es könnte eine beliebige Anzahl von „unzugänglich / ungültig“ Bereichen sein, die nie zu Ihrer App zur Verfügung gestellt werden.

Sie können versuchen, sizeof(int*). Dies gibt Ihnen die Länge (in Bytes) einen Zeiger auf der Zielplattform. So können Sie herausfinden, wie groß der adressierbaren Raum ist.

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