我的應用程序在我寫入的過程中,在內存中上升,似乎不會釋放它。iOS [ARC]應用程序不釋放內存
我想提的第一件事情是,我已經寫了什麼的基本輪廓是這樣的:
- 一個網址(取使用NSData的-initWithContentsOfURL數據)
- 解析的NSData到NSDictionarys的NSArray的使用NSJSONSerialization + JSONObjectWithStream
- 迴路通過解碼NSArray的插入/更新/使用FMDB框架與所述數據刪除記錄在SQLite數據庫解碼
的應用程序執行的上方,但是它確實它在一個循環爲未確定期間的時間,其中應用程序顯示一個「加載」平視顯示器。我認爲可能值得一提的是,雖然我發現它在這個過程中執行的次數是微不足道的,因爲如果它正確釋放,它不會影響內存使用量。如果我在這裏錯了,請告訴我。
我的代碼運行良好,它完成了它的目的。但是,當我剖析應用程序代碼時,內存似乎還在不斷上升。它在整個領域都有所下降,但整體而言仍然在不斷上升(IE並未完全釋放它之前使用的)。
如前所述,我已使用Allocations,Leaks,VM Tracker和Trace Trace Highlights來描述應用程序。
跟蹤亮點:顯示內存使用量逐漸上升,但是在丟棄一些內存(不是全部),這意味着,如果該進程正在運行足夠長的時間內存將達到高使用率和終止。
分配:似乎沒問題。分配有高峯,但總是回落到開始的地方。我把heapshots,他們總是下拉留下每段最大500-700kb(左約10分鐘)
VM跟蹤:證明顯示,內存持續上升,並沒有完全釋放內存(如跟蹤發現強調)。居民似乎得到真正的高
泄漏:沒有在應用程序中發現泄漏
這裏的分配/ VM跟蹤運行的一些截圖:
值得一提的是,其實我已嘗試:
- 添加autoreleasepools
- 「強制釋放」通過分配每個屬性;如NSURL,NSRequests等;以零
我的問題:
- 我應該做一些特別的東西來釋放內存?
- 我該如何進一步調試此問題?
- 我如何才能最清楚地發現樂器給我的數據有什麼問題?
---- 編輯: ----
下面是發送URL請求獲取數據的代碼。:
- (void) requestAndParse : (NSString *)url
{
NSURL *theURL;
ASIHTTPRequest *request;
NSData *collectedData;
NSError *error;
@try {
// File cache the 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 with the records here
...
// remove file
[[NSFileManager defaultManager] removeItemAtPath:[[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"] stringByAppendingString:@"/cachefile.txt"] error:nil];
// release properties used
collectedData = nil;
request = nil;
theURL = nil;
}
}
上述方法在Application Delegate的while循環中被調用。如前所述,while循環的長度不確定。
---編輯2:---
以下是@finally聲明(更新使用FMDB SQLite數據庫)中會發生什麼。我班有很多這樣的方法,每個表都有一個。他們都遵循相同的模式,雖然,因爲它們都是從第一個重複:
-(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;
}
for (NSDictionary *record in records) {
[tdb executeUpdate:@"INSERT OR REPLACE INTO table (attr1, attr2) VALUES (?,?)", [record valueForKey:@"attr1"], [record valueForKey:@"attr2"]];
if ([tdb hadError]) {
queueReturned = NO;
*rollback = YES;
NSLog(@"Failed to insert records because %@", [tdb lastErrorMessage]);
return;
}
}
}];
[dbQueue close];
dbQueue = nil;
}
return queueReturned;
}
,遵循的是-instantiateDatabaseQueue方法:
-(FMDatabaseQueue *) instantiateDatabaseQueue {
@autoreleasepool {
return [FMDatabaseQueue databaseQueueWithPath: [self.getDocumentsDirectory stringByAppendingPathComponent:@"localdb.db"]];
}
}
的autoreleasepools可能使凌亂,但代碼原本沒有這些。我在不同的地方實施它們,看看是否有任何改進(沒有)。
---編輯3 ---
我一直在分析應用程序在過去的幾天,仍然沒有找到答案沒有運氣。我已將相關應用程序的這一部分分離到它自己的單獨項目中,以確保它確實導致了內存使用。事實證明這是正確的,因爲應用程序的表現仍然相同。
我已經拍攝了更多的照片,並且仍然很難確定究竟是什麼錯誤。下面看到,分配看起來沒問題(VM對我來說看起來也不錯),並且仍然沒有泄漏(沒有圖片,因爲沒有!)
但是,當我在Trace亮點是,內存使用量不斷增加,直到達到太多使用量(3GS上大約70 + MB),然後由於使用了太多內存而崩潰。
我通過使用ASIHTTPRequest用於抓取NSData的(存儲到代替文件)降低的問題。請參閱上面的修改代碼。然而,問題仍然存在,只需要更長的時間發生!
按原來,問題:
- 有什麼不對的應用程序的第二部分?
+1不錯的第一個問題。不過,可能需要包含一些代碼。 – 2013-08-23 22:10:35
你有沒有使用stackshots來查看新的分配實際上是什麼?你是否讓runloop有機會運行? (考慮將你的長循環分解爲更小的操作並使用NSOperationQueue處理它們)。 – bneely
我已經提供了發送URL請求,將其分解成一個數組的實際代碼。 – Joshua