使用具有大量元素的NSMutableArray时内存过量

时间:2014-11-07 11:33:12

标签: objective-c xcode memory optimization large-data

当处理大量元素时,我常常遇到一些方法和操作的内存问题。就我而言,我有大约10万个元素的数组。有几个操作导致内存过量,我想知道优化它们的最佳方法。

我正在使用XCode 5.1.1并打开ARC。

以下是几个样本:


1)在NSMutableArray中添加大量元素。

如果检查了某些条件,我需要在数组中添加多个元素:

for(NSString* value in files) {
                if (!condition) {
                    [filesToRemove addObject:value];
                }
        }

文件中的元素数量约为50K - 100K。此示例将导致内存过量。 RAM的使用将开始增加算术级数。所以,为了防止这种情况,我可以把它包装成@autoreleasepool

for(NSString* value in files) {
               @autoreleasepool {
                   if (!condition) {
                       [filesToRemove addObject:value];
                   }
               }
        }

我在这个问题上发现了类似的问题:Do loops and convenience methods cause memory peaks with ARC?

因此,使用@autoreleasepool可以解决这个问题。有更好的解决方案吗?


2)从数组中减去数组。

这个更棘手。我有两个数组,第一个是大约100K,第二个是大约50K,我需要从另一个中减去。

首先尝试:

[files removeObjectsInArray:filesToRemove];

这会导致内存过度杀伤。为什么会这样?在我看来,removeObjectsInArray方法与1)具有相同的行为。我不知道这个方法是如何工作的,但我可以想象,基本上,我们只是在循环中经历一个数组,然后在循环中遍历第二个数组并检查array1中的当前元素是否等于每个元素数组2。

在伪代码中,它看起来像那样:

for (int i = 0; i < files.count; i++)
{
    for (int j = 0; j < filesToRemove.count; j++)
    {
       if ([filesToRemove[j] isEqualTo:files[i]])
       {
            [files removeObject:filesToRemove[j]];
            // perhaps break here?
       }
    }
}

我是对的吗?如果我在代码中使用此代码代替removeObjectsInArray并使用@autoreleasepool,那么会产生与removeObjectsInArray方法相同的效果吗?

更新:我已经在@autoreleasepool尝试了这个,但它没有用。内存使用量仍在增加。关于从大型数组中除外对象的任何想法?


我的问题是:

如何解决问题№2?

使用如此大量数据的最佳方法是什么?这些数组通常包含字符串值。也许使用NSMutableDictionary而不是NSMutableArray会更快?因为,即使我解决内存使用问题,这些操作的速度仍然很慢。

0 个答案:

没有答案