cocoa touch - iOS [ARC] app not releasing memory -
my application, during process i've written, rising in memory , seems not releasing it.
the first thing i'd mention basic outline of i've written this:
- request url (fetching data using nsdata -initwithcontentsofurl)
- parse nsdata nsarray of nsdictionarys using nsjsonserialization +jsonobjectwithstream
- loop through decoded nsarray inserting/updating/deleting records in sqlite database using fmdb framework data decoded
the application above, in loop undetermined period of time, in application displays "loading" hud. thought may worth mentioning this, although find insignificant how many times process, shouldn't affect memory usage if releasing properly. if wrong here, please advise me.
my code works fine, well, it's intended do. however, when profile application code, memory seems keep rising. drop in segments throughout, overall keeps rising (ie doesn't release in full used).
i have, stated, profiled application allocations, leaks, vm tracker, , used trace highlights.
trace highlights: shows memory usage gradually going up, dropping memory (not all) meaning if process running long enough memory reach high usage , terminate.
allocations: seems ok. allocations has spikes comes down started. took heapshots , drop down leaving maximum 500-700kb per segment (left 10 minutes)
vm tracker: proves show memory consistently rises, , not releasing full memory (as discovered in trace highlights). resident seems high
leaks: no leaks found in application
here's screenshots of allocations/vm tracker running:
it's worth noting have in fact tried:
- adding autoreleasepools
- "force releasing" assigning each properties; such nsurls, nsrequests, etc; nil
my questions:
- should doing special release memory?
- how further debug issue?
- how best can find out what's wrong data instruments gives me?
---- edit: ----
here's code sends url request fetch data.:
- (void) requestandparse : (nsstring *)url { nsurl *theurl; asihttprequest *request; nsdata *collecteddata; nserror *error; @try { // file cache nsdata theurl = [[nsurl alloc] initwithstring: url]; request = [asihttprequest requestwithurl: theurl]; [request setdownloaddestinationpath: [[nshomedirectory() stringbyappendingpathcomponent:@"documents"] stringbyappendingstring:@"/cachefile.txt"]]; [request startsynchronous]; [request waituntilfinished]; collecteddata = [[nsdata alloc] initwithcontentsoffile:[[nshomedirectory() stringbyappendingpathcomponent:@"documents"] stringbyappendingstring:@"/cachefile.txt"]]; if ([collecteddata length] > 0) { records = [nsjsonserialization jsonobjectwithdata:collecteddata options:nsjsonreadingmutablecontainers error:&error]; } } @catch (nsexception *exception) { // failed nslog(@"parse error: %@", error); } @finally { // db updates records here ... // remove file [[nsfilemanager defaultmanager] removeitematpath:[[nshomedirectory() stringbyappendingpathcomponent:@"documents"] stringbyappendingstring:@"/cachefile.txt"] error:nil]; // release properties used collecteddata = nil; request = nil; theurl = nil; } }
this above method called within while loop in application delegate. while loop undetermined length, mentioned.
--- edit 2: ---
the following happens within @finally statement (updating sqlite database using fmdb). there lot of these methods in class, 1 each table. follow same pattern though, duplicated first one:
-(bool) insertbatchofrecords:(nsarray *)records { __block bool queuereturned = yes; @autoreleasepool { fmdatabasequeue *dbqueue = [self instantiatedatabasequeue]; [dbqueue intransaction:^(fmdatabase *tdb, bool *rollback) { if (![tdb open]) { nslog(@"couldn't open db inside transaction"); queuereturned = no; *rollback = yes; return; } (nsdictionary *record in records) { [tdb executeupdate:@"insert or replace table (attr1, attr2) values (?,?)", [record valueforkey:@"attr1"], [record valueforkey:@"attr2"]]; if ([tdb haderror]) { queuereturned = no; *rollback = yes; nslog(@"failed insert records because %@", [tdb lasterrormessage]); return; } } }]; [dbqueue close]; dbqueue = nil; } return queuereturned; }
and follows -instantiatedatabasequeue method:
-(fmdatabasequeue *) instantiatedatabasequeue { @autoreleasepool { return [fmdatabasequeue databasequeuewithpath: [self.getdocumentsdirectory stringbyappendingpathcomponent:@"localdb.db"]]; } }
the autoreleasepools may make messy, code did not have these. implemented them in various locations see if there improvement (there not).
--- edit 3 ---
i have been profiling application past few days, , still have no luck in finding answer. have separated part of app in question separate project of it's own, make sure indeed causing memory usage. proved correct, app still acting same.
i have taken further profiling pictures, , still having hard time identifying wrong. see below allocations looks ok (the vm doesn't bad me?), , there's still no leaks (no picture of this, because there's none!!)
however, when profiled on trace highlights, memory usage keeps going up, until reaching usage (around 70+mb on 3gs) , crashes due using memory.
i reduced problem using asihttprequest grabbing nsdata (stores file instead). please see revised code above. however, problem still persists, takes longer happen!
as per originally, question:
- there wrong second part of app process?
using try / catch in ios arc can cause memory leaks, , best avoided.
an alternative approach use async nsurlconnection, or nsoperation synch nsurlconnection.
Comments
Post a Comment