持久分配导致内存增长

时间:2015-03-10 11:27:28

标签: ios objective-c xcode sqlite instruments

我一直在使用Instruments来尝试减少应用程序的内存占用。在“配置文件”模式下运行并在标记代数时选择“泄漏”选项,我注意到我的SQLite数据库类保留了导致内存增长的变量。由于我的应用程序在更新过程中会多次调用这些函数,因此它开始变成一个更大的问题。

第一个函数只是准备SQL语句并绑定可能存在的任何变量:

- (BOOL)prepare:(NSString *)sql withBindings:(NSArray *)bindings {
    if (! sqlite3_prepare_v2(_db, [sql UTF8String], -1, &_statement, NULL) == SQLITE_OK) {
        return NO;
    }

    for (int i = 0; i < [bindings count]; i++) {
        sqlite3_bind_text(_statement,
                          i + 1,
                          [bindings[i] isKindOfClass:[NSNull class]]
                            ? [@"" UTF8String]
                            : [bindings[i] UTF8String],
                          -1,
                          SQLITE_TRANSIENT);
    }

    return YES;
}

,它提供以下信息:

  • 0 libsystem_malloc.dylib malloc_zone_malloc
  • 1 libsqlite3.dylib 0x1958cf588
  • 2 libsqlite3.dylib 0x1958d7f68
  • 3 libsqlite3.dylib 0x19591cc58
  • 4 libsqlite3.dylib 0x195905728
  • 5 libsqlite3.dylib 0x1958d0614
  • 6 libsqlite3.dylib 0x19592a934
  • 7 app - [Db prepare:withBindings:] app / Db.m:68
  • 8 app - [更新更新] app / Update.m:208
  • 9 app __57- [AppDelegate应用程序:didFinishLaunchingWithOptions:] _ block_invoke_2 app / AppDelegate.m:70
  • 10 libdispatch.dylib _dispatch_call_block_and_release
  • 11 libdispatch.dylib _dispatch_client_callout
  • 12 libdispatch.dylib _dispatch_queue_drain
  • 13 libdispatch.dylib _dispatch_queue_invoke
  • 14 libdispatch.dylib _dispatch_root_queue_drain
  • 15 libdispatch.dylib _dispatch_worker_thread3
  • 16 libsystem_pthread.dylib _pthread_wqthread
  • 17 libsystem_pthread.dylib start_wqthread

第二个函数只是遍历行:

- (BOOL)stepThrough {
    return sqlite3_step(_statement) == SQLITE_ROW;
}

,它提供以下信息:

  • 0 libsystem_malloc.dylib malloc_zone_malloc
  • 1 libsqlite3.dylib 0x1958cf588
  • 2 libsqlite3.dylib 0x1958d7f68
  • 3 libsqlite3.dylib 0x19591cc58
  • 4 libsqlite3.dylib 0x195905728
  • 5 libsqlite3.dylib 0x195914a0c
  • 6 libsqlite3.dylib 0x195906dc8
  • 7 libsqlite3.dylib sqlite3_step
  • 8 poc - [Db stepThrough] app / Db.m:79
  • 9 poc - [更新更新] app / Update.m:208
  • 10 poc __57- [AppDelegate应用程序:didFinishLaunchingWithOptions:] _ block_invoke_2 app / AppDelegate.m:70
  • 11 libdispatch.dylib _dispatch_call_block_and_release
  • 12 libdispatch.dylib _dispatch_client_callout
  • 13 libdispatch.dylib _dispatch_main_queue_callback_4CF
  • 14 CoreFoundation __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE _
  • 15 CoreFoundation __CFRunLoopRun
  • 16 CoreFoundation CFRunLoopRunSpecific
  • 17 GraphicsServices GSEventRunModal
  • 18 UIKit UIApplicationMain
  • 19 poc main app / main.m:16
  • 20 libdyld.dylib start

希望有足够的信息让某人说“哦,你还有额外的保留计数”,但如果你需要的话,请告诉我。

1 个答案:

答案 0 :(得分:0)

我发现了我的问题 - 我没有在预备记忆的预备语句中调用sqlite3_finalize。我打电话给你后,我的内存使用量急剧下降。

编辑更多细节,一旦我完成了查询,我运行了一个新功能,我创建了清理任何内存:

- (void)finalise {
    sqlite3_finalize(_statement);
}

其中,对于我的应用程序看起来像这样:

Db * db = [[Db alloc] init];
[db prepare:@"SELECT * FROM `table`" withBindings:@[]];

while ([db stepThrough]) {
    // Do something with data here
}

[db finalise];