Warum schlägt mmap auf iOS fehl?

8

Ich versuche mit mmap Audiodateien auf iOS zu lesen und abzuspielen. Es funktioniert gut für Dateien bis zu 400 MB. Aber wenn ich eine 500MB-Datei versuche, bekomme ich einen ENOMEM-Fehler.

%Vor%

Warum?

Ich wäre glücklich mit einer Antwort wie "700MB ist die Grenze des virtuellen Speichers, aber manchmal ist der Adressraum fragmentiert, also erhalten Sie 700MB, aber in kleineren Stücken". (Das ist nur Spekulation, ich brauche noch eine Antwort)

Die Apple Doc-Seite zum virtuellen Speicher sagt:

  

Obwohl OS X einen Sicherungsspeicher unterstützt, tut dies iOS nicht. Im iPhone   Anwendungen, schreibgeschützte Daten, die sich bereits auf der Festplatte befinden (z. B. Code   Seiten) wird einfach aus dem Speicher entfernt und nach Bedarf von der Festplatte neu geladen.

scheint zu bestätigen, dass mmap für Blöcke funktionieren sollte, die größer sind als der physische Speicher, erklärt aber immer noch nicht, warum ich eine so niedrige Grenze erreiche.

Aktualisieren

  • Diese Antwort ist interessant, aber 500MB ist weit unter dem 700MB Limit, das es erwähnt.
  • Diese Diskussion erwähnt zusammenhängende Speicher Also Speicherfragmentierung könnte ein echtes Problem sein?
  • Ich benutze den iPod Touch der vierten Generation mit 256 MB physikalischem Speicher.
  • Der Zweck meiner Forschung besteht darin, zu überprüfen, ob es eine bessere Möglichkeit gibt, Speicher beim Laden von schreibgeschützten Daten aus Dateien zu verwalten als "Zuweisen, bis eine Speicherwarnung angezeigt wird" . mmap schien eine gute Möglichkeit zu sein, dies zu lösen ...

Update 2

Ich erwarte, dass mmap perfekt mit der neuen 64-Bit-Version von iOS funktioniert. Wird testen, sobald ich ein 64-Bit-Gerät in die Finger bekomme.

    
Tomas Andrle 16.11.2012, 22:45
quelle

4 Antworten

1

Nach weiterer Untersuchung und Lektüre dieses ausgezeichnet Blogpost von John Carmack , hier sind meine Schlussfolgerungen:

  • 700MB ist die Grenze für virtuellen Speicher auf iOS
  • Es kann in einem einzelnen Block verfügbar sein oder auch nicht; Dies ist abhängig vom Gerätezustand und App-Verhalten

Um 700MB Dateidaten zuverlässig zu mappen, ist es daher notwendig, sie in kleinere Stücke zu zerlegen.

    
Tomas Andrle 27.11.2012, 16:20
quelle
1

Ich habe keine Antwort für Sie, aber ich habe Ihren Code auf meinem iPhone 5 mit 6.0.1 und mmap erfolgreich auf einer 700MB ISO-Datei getestet. Also würde ich mit anderen Faktoren beginnen und annehmen, dass mmap ordnungsgemäß funktioniert. Vielleicht ist der Fehler, den du zurück bekommst, nicht wirklich auf Speicher zurückzuführen, oder vielleicht ist der Speicher auf dem Gerät selbst irgendwie erschöpft, wo mmap versagt; Versuchen Sie, das Gerät neu zu starten. Abhängig von deiner iOS-Version frage ich mich auch, ob deine Suche nach dem Ende der Datei dazu führen könnte, dass mmap versucht, die gesamte Datei abzugleichen; Sie könnten versuchen, dies zu bereinigen und stattdessen stat verwenden, um die Dateigröße zu bestimmen, oder schließen Sie den Dateideskriptor vor dem Mappen wieder. Das sind alles nur Ideen; Wenn ich Ihren Fehler reproduzieren könnte, würde ich gerne helfen, es zu beheben.

    
Jonathan Zdziarski 20.11.2012 22:34
quelle
0

Verwenden Sie NSData und berühren Sie mmap nicht direkt hier.

Um die Vorteile fehlerhafter Lesevorgänge zu erhalten, verwenden Sie NSDataReadingMapped. NSData ALSO gibt Bytes in Low-mem-Situationen frei

    
Daij-Djan 17.11.2012 12:29
quelle
0

Normalerweise hat die Größe des verfügbaren physischen Speichers nichts damit zu tun, ob Sie in der Lage sind, eine Datei zu mappen. Dies ist nach allem VIRTUAL Speicher, über den wir sprechen. Das Problem bei iOS ist, dass der Virtual-Memory-Manager nach dem iOS-App-Programmierhandbuch nur schreibgeschützte Abschnitte austauscht ... In der Theorie würde das bedeuten, dass Sie nicht nur durch den verfügbaren Adressraum eingeschränkt werden, Sie sind jedoch auch durch die Menge an verfügbarem RAM eingeschränkt, wenn Sie mit etwas anderem als PROT_READ arbeiten. Siehe Ссылка

Es kann jedoch sein, dass das Problem, das Sie haben, ein Mangel an zusammenhängendem Speicher ist, der groß genug für Ihre Zuordnung im virtuellen Adressraum ist. Soweit ich finden kann, veröffentlicht Apple nicht das obere Speicherlimit eines Benutzermodus-Prozesses. Normalerweise ist der obere Bereich des Adressraums für den Kernel reserviert. Sie können nur 16 Bit Arbeitsspeicher im Benutzermodus verwenden.

Was Sie ohne eine Speicherabbildung im Debugger nicht sehen können, ist, dass es viele (ich zählte über 100 in einer einfachen Beispielanwendung von Apple) shared libraries (dylibs), die in den Prozessadressraum geladen wurden. Jeder von diesen wird auch mmap-in und jeder wird den verfügbaren Adressraum fragmentieren.

In gdb sollten Sie in der Lage sein, die Speicherzuordnungen mit 'info proc mappings' zu sichern. Leider in lldb die einzige Entsprechung, die ich finden konnte, ist "Bildliste", die nur Shared Library Mappings, nicht Daten mmap Mappings zeigt.

Wenn Sie den Debugger auf diese Weise verwenden, sollten Sie feststellen können, ob der Adressraum einen zusammenhängenden Block hat, der groß genug für die Daten ist, die Sie zuordnen möchten !)

    
Andrew Sandoval 05.02.2013 16:16
quelle

Tags und Links