An der Stelle, wo die mmap()
, offene /proc/self/maps
und kopieren Sie den Inhalt in eine temporäre Datei, dann überprüfen Sie die Datei in einem Editor fehlschlägt. Sie sollten ein paar Einträge wie diese:
12e01000-42c00000 ---p 00201000 00:04 11639 /dev/ashmem/dalvik-main space (deleted)
55281000-5d500000 r--s 00000000 00:16 61 /storage/sdcard1/blah
5d500000-67e80000 rw-p 00000000 00:00 0 [anon:libc_malloc]
67ea4000-682cc000 r-xp 00000000 b3:17 114807 /system/vendor/lib/libsc-a3xx.so
682cc000-682f4000 r--p 00427000 b3:17 114807 /system/vendor/lib/libsc-a3xx.so
Die Zahlen auf der linken Seite sind virtuelle Adressbereiche (Beginn/Ende) für den Prozess. Wenn Sie ein neues Mapping erstellen, muss es in die Lücke zwischen den Mappings passen.
Im obigen Beispiel gibt es eine schöne große Lücke zwischen dem Ende des ersten Eintrags bei 0x42c00000 und dem Anfang des nächsten bei 0x55281000. Das sind ungefähr 294 MB. Es gibt keinen Platz zwischen den nächsten zwei und nur einen kleinen danach.
Wenn Sie Ihre Prozesslandkarte betrachten und keine Lücke finden, die groß genug ist, um Ihre Datei zu halten, haben Sie Ihre Antwort. Die Region zwischen 0x00000000 und 0xbfffffff ist in der Regel für 32-Bit-Apps verfügbar, aber das App-Framework verbraucht einen großen Teil davon. (Die oberste 1GB ist dem Kernel zugeordnet.)
Meine Vermutung ist, dass einige Kombination von ASLR und Änderungen an der Art, wie virtueller Speicher in Lollipop zugeordnet ist, zu diesem Problem geführt haben. In der Karte, die an this similar question angefügt ist, war die größte gefundene Lücke etwa 300 MB. Es gibt zwei große "Dalvik" Regionen, eine 768MB (bei 12e01000), eine 1.2GB (bei 84d81000). (Da Sie Lollipop betreiben, sind diese eher auf ART als auf Dalvik zurückzuführen, aber anscheinend blieb das Label hängen.)
Eine Möglichkeit besteht darin, dass ART höhere Anforderungen an den virtuellen Speicher stellt als Dalvik, und die großen Zuordnungen machen es für Anwendungen schwierig, große zugeordnete Bereiche zu erhalten. Es ist auch möglich, dass ART aufgrund eines Fehlers zu viel Speicherplatz belegt. Vielleicht möchten Sie auf Marshmallow testen, um festzustellen, ob etwas repariert wurde.
In jedem Fall können Sie kein Mapping erstellen, wenn kein zusammenhängender virtueller Speicheradressbereich groß genug ist, um es aufzunehmen. Mit der App-Framework-Nutzung und den enormen ART-Zuordnungen, die in der anderen Frage zu sehen sind, wäre eine 768 MB-Zuordnung nicht möglich, selbst wenn der virtuelle Adressraum nicht fragmentiert wäre. Sie müssen kleinere Abschnitte der Datei zuordnen und sie möglicherweise während der Arbeit entfernen, um Platz zu schaffen.
Es könnte sich lohnen, einen Fehler auf b.android.com zu archivieren. Hängen Sie eine Kopie Ihrer Prozesslandkartendatei an und legen Sie die Version von Android und Gerät fest.
Für ein bisschen mehr über die Interpretation/proc/Karten-Ausgabe, siehe z.B. this answer.
Die Fehlermeldung scheint ziemlich offensichtlich; Haben Sie überprüft, ob genügend Speicher verfügbar ist? – Phillip
Ich kenne keine zuverlässige Methode, um genau zu prüfen, wie viel Speicher frei und zugänglich ist. Allerdings ist das nicht wirklich der Teil, den ich nicht verstehe - ich verstehe nicht, warum der gleiche Code auf dem gleichen Gerät mit Android 4.4 funktioniert und dann auf 5.0 fehlschlägt. Es ist unwahrscheinlich, dass der Speicherbedarf von Android so stark zugenommen hat. Ich denke, dass es wahrscheinlicher ist, dass ein neues Compiler-Flag oder ähnliches benötigt wird. – sigmabeta
Verwenden Sie einfach 'adb shell free -m' von einem angeschlossenen PC. Wenn Sie keinen Zugriff auf ein Gerät haben, bietet SO verschiedene Lösungen für die Abfrage des verfügbaren Speichers von C in Linux. (Du solltest * wirklich * das tun.) – Phillip