Memory Management Unterschiede zwischen DEBUG und RELEASE Build?

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Memory Management Unterschiede zwischen DEBUG und RELEASE Build?

    Ich habe ein Problem mit einem Unterschied beim Memory Management von iOS, je nachdem ob ich ein DEBUG oder RELEASE Build der App erstellt.

    Nachfolgend erst mal das Verhalten vom DEBUG Build, also in dem man ja normalerweise seine Apps entwickelt und testet.

    Um zu verhindern, dass die App bei der Verarbeitung von sehr großen Dateien ggf. eine Memory Warnung erhält und beendet wird, wollte ich vorab prüfen, ob der benötigte Speicher der App auch zur Verfügung steht. Ich fordere daher per malloc() Speicher in der benötigten Größe an. Wenn der angeforderte Speicher nicht eh schon den RAM Speicher des iPads überschreitet, erhält man diesen auch. Anderenfalls wir NULL zurückgegeben. Soweit ok. Selbst wenn man den Speicher jetzt erhalten hat, heisst dies ja nicht, dass man diesen dann auch komplett verwenden darf. Also fülle ich den Speicher in kleinen Blöcken mit Dummy Daten und prüfe, per registrierter UIApplicationDidReceiveMemoryWarningNotification, ob es zwischenzeitlich eine Memory Warning gibt. Ist dies der Fall, dann hat sich die Sache für mich erlegt und die Daten können auf diesem iPad nicht verarbeitet werden. Anderenfalls kommt es bei der Verarbeitung leider zu mehreren Memory Warnings, auf die nicht mehr reagiert werden kann, und die App wird von iOS beendet. Mit dem Verhalten bin ich soweit zufrieden.

    Das Problem ist jetzt, dass iOS für einen RELEASE Build ein komplett anderes Verhalten beim Memory Management hat.

    Bei einem RELEASE Build erhalte ich immer den Speicher in der angeforderten Größe und kann diesen auch komplett mit Dummy Daten füllen, ohne eine Memory Warnung zu erhalten. Man kann sogar die bis zu 5-fache Größe (ca. 4GB) an Speicher anfordern und mit Dummy Daten füllen, ohne eine einzige Memory Warning zu erhalten. Eigentlich super und man sollte sich darüber freuen. Wenn ich dann allerdings versuche die sehr großen Datei zu verarbeiten erhält die App mehrere Memory Warnings, auf die dann nicht mehr reagiert werden kann, und die App wird von iOS beendet. Was soll dieser Blödsinn? ?(

    Lässt sich das Memory Management einer App ggf. über die Build Settings konfigurieren? Ich würde gerne für den RELEASE Build das Verhalten vom DEBUG Build verwenden, falls dies möglich ist. Welche Alternativen gibt es?
  • Was mir gerade nicht ganz klar ist. Du füllst den Speicher mit kleinen Blöcken von Dummy-Daten. Soweit so gut. Nun sagst du wenn du die "echten" Daten nimmst gibt es die Warnings beim verarbeiten. Also lädst du die "echten" Daten auch in kleinen Teilen und willst danach mit dem Gazen arbeiten und das geht erst nicht oder wie darf ich das verstehen?

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Beim meinem Speicher Test, muss ich den Speicher in kleinen Blöcken, mit memset() füllen, um auf eine Memory Warning reagieren und dann abbrechen zu können. Würde ich den kompletten Speicher in einem Block per memset() füllen, dann kann ich nicht mehr auf eine Memory Warning reagieren und die App wird direkt von iOS beendet, bevor memset() fertig ist.

    Die Verarbeitung der Daten erfolgt komplett in einem externen Framework, diese Aktion kann ich leider auch nur anstoßen und habe dann keine Kontrolle mehr darüber. Entweder läuft die App dann noch oder wurde zwischenzeitlich einfach von iOS beendet. :(

    Ich teste gerade mal, die Verarbeitung der Daten durch das externe Framework in eine NSBlockOperation zu packen, welche ich dann beim Erhalt einer Memory Warning vorzeitig beenden kann. Ich bin gerade noch dabei und hoffe, dass dies funktioniert und somit eine Alternative wäre.
  • Ist es nicht eher anzunehmen, dass das externe FW noch mehr Speicher braucht, weil es mit den Daten arbeitet? Von daher wird es sicher nicht reichen nur den Speicher für die Daten selber auszutesten oder?

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Meine aktuelle Lösung funktioniert im DEBUG ja ohne Probleme. Ich verstehe nur nicht, warum Apple/iOS ein komplett anderes Verhalten bei einem RELEASE Build der App verwendet. Was soll dieser Blödsinn? ?(

    Mir würde es schon reichen, wenn ich das Memory Management Verhalten vom DEBUG Build auch im RELEASE Build der App hätte.

    Hm, mit der NSBlockOperation Alternative komme ich leider auch nicht weiter, da ich die Operation zwar canceln, aber nicht direkt beenden kann. Hier müsste das externe Framework dann auf die cancelation reagieren, was natürlich nicht der Fall ist. :(
  • macmoonshine schrieb:

    Was macht denn das Framework?
    Es handelt sich um FMDB (an Objective-C wrapper around SQLite). Ich versuche aus einer DB mehrere Blobs zu laden und im Dateisystem zu speichern. Fragt mich nicht warum dies so gemacht wird, es ist eine bestehende App. Allerdings gibt es seit kurzem auch Blobs die zwischen 500 und 900 MB groß sind und somit taucht das Problem mit den Memory Warnings und dem Beenden der App durch iOS auf. Jetzt soll die App natürlich nicht einfach nur "abstürzen" bzw. von iOS beendet werden, sondern dieses Problem soll abfangen und eine Meldung ausgeben werden. Für den DEBUG Build habe ich ja auch eine Lösung gefunden die wunderbar funktioniert.

    Mir war leider nicht klar, das Apple/iOS Unterschiede beim Memory Management zwischen einem DEBUG und einem RELEASE Build macht. :(

    Ich muss jetzt eine Lösung finden, die auch bei einem RELEASE Build funktioniert.

    Exact gibt es Probleme bei FMDB bei der Methode nextWithError: von FMResultSet. Diese ermittelt die nächste Zeile aus dem Ergebnis der letzten Query. Im Grunde genommen wird darin einfach nur direkt sqlite3_step() aufgerufen. Wenn es innerhalb von sqlite3_step() eine bzw. mehrere Memory Warnings gibt, dann beendet iOS App leider, bevor die App darauf irgendwie reagieren könnte.
  • Hast Du auch ein Beispiel wie ich dies verwenden kann? Habe es schon mit sqlite3_config(SQLITE_CONFIG_MMAP_SIZE,xxx,yyy) probiert, aber war damit wohl nicht wirklich erfolgreich.

    Kann man dies in der von Apple im iOS SDK zur Verfügung gestelltem libsqlite3 Library überhaupt verwenden (SQLITE_MAX_MMAP_SIZE)?
  • Ok, verwende jetzt die aktuelle SQLite Version in der App. Dies führt zwar leider nicht dazu, dass sich die großen Blobs jetzt verarbeiten lassen, allerdings erhalte ich im DEBUG und RELEASE Build jetzt einen Memory Fehler von SQLite und die App stürzt nicht mehr ab bzw. wird von iOS beendet. :thumbsup: