【问题标题】:How do I get my memory cleaned up?如何清理我的内存?
【发布时间】:2014-03-16 17:41:21
【问题描述】:

我有一个图像处理应用程序,用于测试 iOS 上块/线程的潜在加速。该算法运行良好,使用了大量内存,然后在运行后将其转储。

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

每次运行都使用大约 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];
}

【问题讨论】:

  • 有相关代码可以分享吗?
  • @Merlevede 我不确定它是否有帮助,但我已经在 testSuite 中进行了编辑。我可以理解内存问题,因为imageManipulatorobjectRecognizer 拥有完整的图像像素数据数组。我希望消除引用会清除它们
  • 您可以将代码发布到processImageInParallel: 方法吗?每张图片有多大?

标签: ios iphone objective-c memory


【解决方案1】:

除了研究提高内存使用率的算法之外,您还可以试一试@autoreleasepool。这将释放在每个循环之间使用的可释放对象,而无需结束当前循环循环。

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

来自documentation

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

【讨论】:

  • 成功了,谢谢!它现在最大约为 90 MB,我可以管理和处理。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    这里应该使用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];
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-18
      • 2023-04-06
      • 1970-01-01
      • 2021-11-24
      • 2014-03-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多