2016-11-21 3 views
1

Ich muss einige Dateien in meiner iOS App importieren und die Daten an eine andere Schicht weiterleiten (via MessagePack).ios: Speicherverbrauch beim Lesen einer großen Datei

Die importierte Datei kann ziemlich groß sein, deshalb kann ich sie nicht vollständig im Speicher laden und muss sie lesen und weiterleiten. Dazu verwende ich eine NSInputStream, und jedes Mal, wenn es mir ein paar Daten gibt, packe ich es und weiterleiten. Aber seltsamerweise ändert dies nicht die Speichernutzung des Prozesses, als ob die Datenblöcke sofort freigegeben würden.

Der Prozess dieses Stück Code simuliert werden könnte, wo ich Zufallsdaten erzeugen und seine Bytes extrahieren (das ist der Hauptteil der Message Verpackung, die den Speicher verwendet):

for(int i = 0; i < 200; i++) { 
    NSData *theData = [self generateRandomData]; 
    const char *buf = ((NSData*)theData).bytes; 
} 

Die Verwendung Speicher springt und erreicht ~ 450MB (die generateRandomData erzeugt ein 2MB Datenstück) und sinkt dann nach dem Ende der for Schleife auf ihren regulären Pegel ab.

Ich hätte gedacht, dass die buf Variable nach jeder Schleife Iteration freigegeben werden sollte, und daher die Speicherauslastung nie sehr hoch gehen.

Warum ist das nicht der Fall? Fehle ich etwas?

Wie könnte ich dann eine große Datei importieren? Ich habe darüber nachgedacht, während des Prozesses eine kurze Pause zu machen (alle 100MB importiert oder so), um die Speicherauslastung zu verringern, aber es erscheint mir nicht ideal.

+0

Bei Verwendung von ARC ist die Speicherfreigabe nicht in unserer Hand und wird vom System entschieden. Interessant dabei ist, dass der gleiche Ort im Stapel wie gesagt überlastet ist. Upvoted. – arqam

+0

@arqam, Sie liegen falsch. Es ist in der Umgebung mit Garbage Collection Deallokation wird vom System entschieden. In ARC wie in MRC wird der Speicher vom Programmierer verwaltet, aber auf eine bequemere Weise. –

+0

Haben Sie App auf Speicherlecks überprüft? –

Antwort

1

Ich habe auch das gleiche Problem der Speicherauslastung in meiner Anwendung, wie es 600 MB erreicht, dann gebe ich den Speicher manuell mit einem Autorelease-Pool.

Erstellen Sie einen Autorelease-Pool und überprüfen Sie dann Ihre Speicherauslastung .Hope this Hilft Ihnen.

+1

Was haben Sie davon bekommen? Weil die Iterationen immer noch im 'Autoresposepool' liegen. – arqam

+0

Ich habe diese Antwort akzeptiert, da die Lösung darin bestand, den 'buf' in einen' autoresposepool' zu setzen, aber @arqam hat Recht, der '@ autoreleasepool' sollte innerhalb der for-Schleife liegen, so dass die' buf' Variable freigegeben wird jede Iteration. @mukul vielleicht könnten Sie Ihre Antwort bearbeiten, damit andere nicht irregeführt werden? – ink

Verwandte Themen