【问题标题】:Need help with a loop that gobbles up RAM需要帮助解决一个吞噬 RAM 的循环
【发布时间】:2011-10-29 07:25:43
【问题描述】:

我正试图让这个循环释放它使用的所有内存,但它仍然很快就会吞噬 RAM。希望有人能告诉我如何让字符串按应有的方式释放。基本上,循环将 double 写入文本文件,有时它必须写入几兆字节。

for (int i = 0; i < number_of_samples; i++)
{
    if (print_str == nil)
    {
        print_str = [[NSMutableString alloc] init];
    }

    NSString* add_str = [[NSString alloc] initWithFormat:@"\n%0.06f", number_of_seconds/number_of_samples*i];
    [print_str appendString:add_str];
    [add_str release];

    for (int g = 0; g < number_of_channels; g++)
    {
        add_str = [[NSString alloc] initWithFormat:@"\t%f", data_buffer[g + i*number_of_channels]];
        [print_str appendString:add_str];
        [add_str release];
    }

    if (i % 100 == 0 && i != 0)
    {
        fprintf(c_file_handle, "%s", [print_str UTF8String]);
        [print_str release];
        print_str = nil;
    }
}

【问题讨论】:

  • 我试过了。分配新的 NSStrings 只是我最近尝试过的事情。
  • 你有没有试过打开仪器,看看你的记忆实际上是从哪里跑掉的?也许分配可能会有所帮助。

标签: objective-c ios memory-management nsstring


【解决方案1】:

您可以尝试使用NSOutputStream,而不是创建字符串并使用fprintf。您的代码可能如下所示:

NSOutputStream *os = [NSOutputStream outputStreamToFileAtPath:@"/path/to/file.ext"
                                                       append:YES];
[os open];
for (int i = 0; i < number_of_samples; i++) {
    // create a buffer to store the data to write
    [os write:buffer maxLength:bufferLength];
    // release the buffer
}
[os close];

这是一个粗略的草图 - 有关详细信息,请参阅 NSStreamNSOutputStream 的文档。

【讨论】:

    【解决方案2】:

    您可以对字符串做的唯一事情是不使用 print_str,因为它仍然保存所有字符串并占用内存。使用 fopen 中的 "a" 选项将数据追加到文件中,并将格式化字符串 add_str 追加到文件中,而不是将其添加到内存中缓冲。

    【讨论】:

    • 这让我找到了解决方案。不是 NSStrings 占用空间,而是文件缓冲区。现在我定期关闭然后打开文件,这可以降低内存使用量:)
    【解决方案3】:

    因为您基本上是使用那个字符串作为临时缓冲区,所以如何分配一次,然后根据需要多次进行 initWithFormatting 呢?完成循环后释放它。

    NSString * add_str = [NSString alloc];
    
    loop... {
        NSString* add_str = [ add_str initWithFormat:@"\n%0.06f", number_of_seconds/number_of_samples*i];
        [print_str appendString:add_str];
    }
    // end of loop
    
    [add_str release];
    

    【讨论】:

    • 我不会尝试多次初始化单个对象。这绝对不是预期的操作。此外,对于像 NSString 这样的类集群,您永远无法确定初始化程序不会释放分配的对象并返回给您一个不同的对象。
    • 这个想法还不错。不用再次初始化,可以清除。
    【解决方案4】:
    1. 您可以使用[print_str appendFormat:],而不是每次都分配和释放一个新字符串。

    2. 在紧密循环中运行时,有时您需要创建一个 NSAutoRelease 池并定期排空它并创建一个新池,但我没有看到您使用任何自动释放的对象。

    3. 您是否可以随时使用freedata_buffer,还是以后再使用它? free(data_buffer[g + i*number_of_channels]);

    【讨论】:

    • (1) 可能有助于提高性能,但不应改变内存使用。 (2) 无济于事,因为一开始就没有将任何内容添加到自动释放池中。
    • 这些只是建议,我知道 2) 没有明确使用任何自动释放的对象,但你永远不知道内部使用了哪些方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-07
    • 1970-01-01
    • 1970-01-01
    • 2013-05-24
    • 1970-01-01
    • 2012-07-14
    相关资源
    最近更新 更多