ios - 为什么这个 for 循环会耗尽内存?

标签 ios memory memory-management memory-leaks sskeychain

我正在为我的 iOS 项目使用 ARC,并使用名为 SSKeychain 的库来访问/保存项目到钥匙串(keychain)。我希望我的应用程序在峰值负载时每 10 秒左右访问一次钥匙串(keychain)项(以访问 API 安全 token ),因此我想测试这个库以了解它在频繁调用时如何处理。我做了这个循环来模拟大量的调用,并注意到它在 iPhone(不是模拟器)上运行时会消耗大量(~75 mb)内存:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    dispatch_async(dispatch_get_main_queue(), ^{
        NSUInteger beginMemory = available_memory();
        for (int i = 0; i < 10000; ++i) {

            @autoreleasepool{
                NSError *  error2 = nil;
                SSKeychainQuery*  query2 = [[SSKeychainQuery alloc] init];
                query2.service = @"Eko";
                query2.account = @"loginPINForAccountID-2";
                query2.password = nil;
                [query2 fetch:&error2];
            }
        }
        NSUInteger endMemory = available_memory();

        NSLog(@"Started with %u, ended with %u, used %u", beginMemory, endMemory, endMemory-beginMemory);
    });

    return YES;
}

static NSUInteger available_memory(void) {
    // Requires #import <mach/mach.h>
    NSUInteger result = 0;
    struct task_basic_info info;
    mach_msg_type_number_t size = sizeof(info);
    if (task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size) == KERN_SUCCESS) {
        result = info.resident_size;
    }
    return result;
}

我正在使用可以找到的 SSKeychain here .这个测试会消耗大约 75 MB 的内存,不管 key 链上是否真的存储了东西。

知道发生了什么事吗?我的测试方法有缺陷吗?

最佳答案

我在 Leaks Instrument 下运行了你的代码,这是我从 Allocations 轨道上看到的 -

Allocations Track

这是您所期望的 - 在循环期间分配了大量内存,然后释放。

看着你看到的细节-

Detail

2.36MB 堆上的持久字节 - 这是应用“现在”实际使用的内存(即在应用“空闲”循环之后)

持久对象数为 8,646 - 同样,“现在”分配的对象数。

transient 对象 663,288 - 在应用程序生命周期内在堆上创建的对象总数。从transient和persistent的区别可以看出大部分已经发布了。

总字节数 58.70MB - 这是执行期间分配的内存总量。不是使用中的内存总量,而是已分配的内存总量,无论这些分配是否随后被释放。

浅粉色和深粉色条之间的差异还显示了当前“事件”内存使用量与总使用量之间的差异。

您还可以从“泄漏检查”轨道中看到未检测到泄漏。

因此,总而言之,您的代码使用了很多临时内存,正如您所期望的紧密循环一样,但您不会在应用程序执行的正常过程中看到这种内存使用,其中钥匙串(keychain)被访问了几次每秒或每分钟或任何时间。

现在,我可以想象,在努力增加堆以支持所有这些对象之后,iOS 不会立即将现在释放的堆内存释放回系统;您的应用程序稍后可能再次需要大堆空间,这就是为什么您的代码报告大量内存正在使用以及为什么您应该警惕尝试构建自己的工具而不是使用可用工具的原因。

关于ios - 为什么这个 for 循环会耗尽内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33288757/

相关文章:

ios - 为什么交易在启动时被更新?

c - 如果需要,堆栈会分配更多空间还是会溢出?

c - ENOMEM 来自 popen() 的 system(),同时有足够的内存

c++ - 如何正确实现 C++ 类析构函数

java - Linux 核心转储与堆转储?

c++ - 什么时候通过引用传递不是一个好主意?

ios - Realm :在一对多关系中,如何根据本例中的类别获取记录

ios - 无法将类型 'TestApplication.ViewControllerResultat' 的值转换为 'TestApplication.ViewControllerForkertKorrektSide'

ios - 如果应用重定向失败,尝试在 Safari 中启动 Twitter

php - MySQL 数据库导出 : Allowed memory size of 67108864 bytes exhausted