如何清理记忆?

时间:2014-03-16 17:41:22

标签: ios iphone objective-c memory

我有一个图像处理应用程序,我用它来测试iOS上的块/线程的潜在加速。该算法工作正常,使用相当数量的内存,然后运行后转储它。

我制作了一个测试套件,按顺序运行算法10次,使用并行实现运行10次。如果我尝试在手机上运行它会因内存压力而崩溃 - 它最终需要大约432MB的内存。但是,一旦套件完成,它最终都会被清理:/

enter image description here

每次运行都使用大约25MB的内存。所以我认为解决方案是在每次运行后重置所有对象并将它们清理干净。我基本上有2个处理对象来完成我的所有工作。所以在每次运行之后我都认为将它们设置为nil将导致它们被重新创建并且旧版本被销毁并且内存被释放。但是,它对我的​​内存使用没有影响。

我是否还需要做些什么才能在两次通话之间释放内存?我认为Objective-C现在正在使用引用计数,并且一旦我消除了唯一的引用 - 在我的viewController中 - 它将被释放。任何建议将不胜感激。

这是我试图释放内存的测试套件算法:

- (void)runTestSuite
{
    // Sequential
    NSLog(@"Sequential Run: ");
    for (int i = 0; i < 10; i++) {
        self.imageView.image = self.startImage;
        self.imageManipulator = nil;
        self.objectRecognizer = nil;
        for (UIView *view in self.gameView.subviews) {
            [view removeFromSuperview];
        }
        [self processImageInParallel:NO];
    }
    [self printResults];
    [self clearResults];
    // Parallel
    NSLog(@"Parallel Run: ");
    for (int i = 0; i < 10; i++) {
        self.imageView.image = self.startImage;
        self.imageManipulator = nil;
        self.objectRecognizer = nil;
        for (UIView *view in self.gameView.subviews) {
            [view removeFromSuperview];
        }
        [self processImageInParallel:YES];
    }
    [self printResults];
    [self clearResults];
}

3 个答案:

答案 0 :(得分:1)

一些源代码会有所帮助。如果没有这个,一般的建议是:在自动释放池中包装正在进行图像处理的代码(参见this Apple document)。

这将尽快丢弃临时对象,减少内存峰值。

答案 1 :(得分:1)

除了使用算法来提高内存使用率之外,你可以给@autoreleasepool一个镜头。这将释放每个循环之间使用的可用对象,而不需要结束当前循环周期。

for (int i = 0; i < 10; i++) {
    @autoreleasepool {
    }
}

来自documentation

  

在许多情况下,允许临时对象累积直到   当前事件循环迭代的结束不会导致过多   高架;但是,在某些情况下,您可能会创建一个大数字   临时对象,大大增加了内存占用和   你想要更快地处置。在后面这些情况下,你   可以创建自己的自动释放池块。在街区尽头,   临时对象被释放,这通常导致他们的   解除分配从而减少程序的内存占用

答案 2 :(得分:1)

Autorelease pool应该在这里使用

  

许多程序会创建自动释放的临时对象。这些   对象添加到程序的内存占用,直到结束   块。在许多情况下,允许临时对象累积   直到当前事件循环迭代结束才导致   过度开销;但是,在某些情况下,您可以创建一个   大量临时对象大量增加内存   足迹和你想要更快地处置。在这些   在后一种情况下,您可以创建自己的自动释放池块。在   块的结尾,临时对象被释放,这通常是   导致他们的释放,从而减少程序的内存   足迹

- (void)runTestSuite
{
    // Sequential
    NSLog(@"Sequential Run: ");
    for (int i = 0; i < 10; i++) {
        @autoreleasepool
        {
            self.imageView.image = self.startImage;
            self.imageManipulator = nil;
            self.objectRecognizer = nil;
            for (UIView *view in self.gameView.subviews) {
                [view removeFromSuperview];
            }
            [self processImageInParallel:NO];
        }
    }
    [self printResults];
    [self clearResults];
    // Parallel
    NSLog(@"Parallel Run: ");
    for (int i = 0; i < 10; i++) {
        @autoreleasepool
        {
            self.imageView.image = self.startImage;
            self.imageManipulator = nil;
            self.objectRecognizer = nil;
            for (UIView *view in self.gameView.subviews) {
                [view removeFromSuperview];
            }
            [self processImageInParallel:YES];
        }
    }
    [self printResults];
    [self clearResults];
}