Speicher Warnung und crash (ARC) - wie zu erkennen, warum es passiert?

Habe ich angefangen, die ARC seit kurzem und dann habe ich die Schuld für jedes einzelne problem mit dem Arbeitsspeicher. 🙂 Vielleicht könnten Sie mir helfen, besser zu verstehen, was ich falsch mache.

Mein Aktuelles Projekt ist über CoreGraphics eine Menge - Diagramme zeichnen, Ansichten gefüllt mit miniaturen und so weiter. Ich glaube, wäre es kein problem, während mit der manuellen Speicherverwaltung, außer vielleicht ein paar zombies... Aber jetzt, Applikation einfach so abstürzt jedes mal, wenn ich versuche, um entweder eine Menge von thumbnails oder zeichnen ein wenig komplizierter, chart.

Während der profiling-Instrumente kann ich sehen, ein enorm hoher Wert im Residenten Speicher sowie in der schmutzigen. Heap Analyse zeigt eher beunruhigend unregelmäßig wachsen...

Beim zeichnen nur ein paar Vorschaubilder, Residenten Speicher wächst für über 200 MB. Wenn alles gezeichnet ist, Speicher sinkt wieder auf fast den gleichen Wert wie vor dem auftragen. Jedoch, eine Menge miniaturen, ein Wert in Residenten Speicher ist höher als 400 MB und natürlich stürzt die app. Ich habe versucht, zu begrenzen Sie die Anzahl der miniaturen gezeichnet, in der gleichen Zeit (NSOperationQueue und seine maxConcurrentOperationCount), aber wie die Freisetzung von so viel Arbeitsspeicher scheint mal etwas mehr Zeit nehmen, hat es nicht wirklich das Problem zu lösen.

Jetzt meine app im Grunde gar nicht funktionieren, da die realen Daten arbeitet mit einer Menge von komplizierten charts = Menge von thumbnails.

Jeder Miniaturansicht wird erstellt, mit diesem code hab ich von hier: (Kategorie UIImage)

+ (void)beginImageContextWithSize:(CGSize)size
{
    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
        if ([[UIScreen mainScreen] scale] == 2.0) {
            UIGraphicsBeginImageContextWithOptions(size, YES, 2.0);
        } else {
            UIGraphicsBeginImageContext(size);
        }
    } else {
        UIGraphicsBeginImageContext(size);
    }
}

+ (void)endImageContext
{
    UIGraphicsEndImageContext();
}

+ (UIImage*)imageFromView:(UIView*)view
{
    [self beginImageContextWithSize:[view bounds].size];
    BOOL hidden = [view isHidden];
    [view setHidden:NO];
    [[view layer] renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    [self endImageContext];
    [view setHidden:hidden];
    return image;
}

+ (UIImage*)imageFromView:(UIView*)view scaledToSize:(CGSize)newSize
{
    UIImage *image = [self imageFromView:view];
    if ([view bounds].size.width != newSize.width ||
        [view bounds].size.height != newSize.height) {
        image = [self imageWithImage:image scaledToSize:newSize];
    }
    return image;
}

+ (UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize
{
    [self beginImageContextWithSize:newSize];
    [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    [self endImageContext];
    return newImage;
}

Gibt es eine andere Möglichkeit, die würde es nicht Essen, so viel Speicher oder ist etwas wirklich falsch mit dem code bei der Verwendung von ARC?

Dem anderen Ort, wo der Speicher Warnung + crash passiert ist, wenn es zu viel Neuzeichnen von einer beliebigen Ansicht. Es muss nicht schnell sein, nur viele Male. Speicher-stacks, bis es kracht und ich bin nicht in der Lage, etwas zu finden, wirklich für Sie verantwortlich. (Ich sehe eine wachsende resident/schmutzigen Speicher in der VM-Tracker und ein heap Wachstum in den Zuführungen instrument)

Meine Frage ist also: wie finden, warum es auch passiert? Mein Verständnis ist, wenn es keinen Besitzer für das Objekt gegeben, es ist freigegeben so bald wie möglich. Meine Inspektion der code schlägt eine Menge von Objekten werden nicht freigegeben, selbst wenn sehe ich keinen Grund, dass es passiert. Ich weiß nichts über irgendwelche behalten Zyklen...

Ich gelesen habe, durch die Umstellung auf ARC Release Notes, bbum ' s Artikel über heap Analyse und wahrscheinlich ein Dutzend anderer. Unterscheidet sich irgendwie heap Analyse mit und ohne ARC? Ich kann nicht scheinen, etwas nützliches zu tun mit seiner Ausgabe.

Danke für alle Ideen.

UPDATE: (nicht zwingen, alle Lesen, alle Kommentare und an mein Versprechen halten)

Durch gezielt immer durch meinen code und das hinzufügen von @autoreleasepool, wo es hatte keinen Sinn, Speicherverbrauch bekam gesenkt. Das größte problem war die Berufung UIGraphicsBeginImageContext aus hintergrund-thread. Nach der Fixierung (siehe @Tammo Freese Antwort für details) Freigabe trat bald genug, um nicht zum Absturz einer app.

Meinem zweiten crash (verursacht durch viele Neuzeichnen des gleichen Diagramms), war völlig gelöst indem CGContextFlush(context) am Ende meiner Zeichnung Methode. Schande über mich.


Eine kleine Warnung für jeden, der versucht, etwas ähnliches zu tun: OpenGL verwenden. CoreGraphics ist nicht schnell genug für Animation big Zeichnungen, vor allem nicht auf einem iPad 3. (die erste mit retina)

InformationsquelleAutor der Frage xius | 2012-07-20

Schreibe einen Kommentar