【问题标题】:App not releasing the memory, Memory use is getting doubled every time应用程序不释放内存,内存使用量每次都增加一倍
【发布时间】:2015-12-25 10:45:34
【问题描述】:

我创建了一个函数来帮助在NSString 数组中查找重复文件(数组包含文件路径)

这是我的功能:

-(NSMutableArray *)compareWithList:(NSMutableArray*)fileCompareList // list of file from which we need to find the duplicates of the target
                          fileData:(NSData*)_fileData // contains target file data bytes
                        fileLength:(UInt32) _fileLenght // contains size of target file
{
    // result list of the (duplcate)files
    NSMutableArray* fileList = [[NSMutableArray alloc]init];

    // flag to check if the path is a folder
    BOOL isDir;

    //stores the size of the file that is being itrated
    UInt32 size = 0;
    //stores the byte data of the file that is being itrated
    NSData *bytes = nil;

    //itrating the files in the list one by one in order find the duplicate
    for (NSString* sPath in fileCompareList) {
        //checking if the file already exists in the result list
        if ([fileList indexOfObject:sPath] == NSNotFound)
        {
            //getting the size of the file
            UInt32 size = [sysHelp getSizeOfFile:sPath];
            //if the size matches of the target file and the itrated file then go inside
            if(size == _fileLenght)
            {
                //get the bytes of the file being itrated
                bytes = [[NSData alloc] initWithContentsOfFile:sPath];

                //if the bytes matches then add the itrated file into the result list
                if([bytes isEqualToData:_fileData])
                {
                    [fileList addObject:sPath];
                }
                //remove the itrated file data from the array
                bytes = nil;
            }
        }

    }

    return fileList;
}

这里的问题是由于函数内存使用率越来越高,如下面的屏幕截图所示:

之前

之后

一段时间后

注意;我正在使用 ARC

我如何调用函数?在这里:

NSMutableArray* allFilesOfSystem =[[NSMutableArray alloc] init];
allFilesOfSystem = self AllFilesOfDesktopAndSubDirectores];

NSMutableArray* FinalResultArray = [[NSMutableArray alloc] init];

for (int i = 0; i < [allFilesOfSystem count]; i++) {

        NSString* filePath = [allFilesOfSystem objectAtIndex:i];

        //file to byte array
        NSData *bytes = [[NSData alloc] initWithContentsOfFile:filePath];

        //file size
        UInt32 size = [sysHelp getSizeOfFile:filePath];

        [FinalResultArray addObjectsFromArray:[self compareWithList:allFilesOfSystem fileData:bytes fileLength:size]]

}

【问题讨论】:

  • @ElTomato 你听说过自动引用计数吗?
  • 天哪。我也没有问你。我正在回复 ElTomato。
  • 是什么让你觉得内存被浪费了?内存使用条表示从系统获取的 RAM 量。并不是说被App占用了。如果内存使用量达到“危险”值,会发生什么?数百 MB 并不危险。
  • 简单地做,@Inder 从我的 cmets 偷了什么。
  • @VikasBansal 如果 autoreleasepool 对你有用,那么用 autoreleasepool 包装调用函数代码(你最后添加到问题中)因为我看到你也在那里分配 NSData 实例。

标签: objective-c cocoa automatic-ref-counting


【解决方案1】:

请将您的所有陈述移至@ autoreleasepool,如果有帮助,请告诉我。下面是代码

-(NSMutableArray *)compareWithList:(NSMutableArray*)fileCompareList // list of file from which we need to find the duplicates of the target
                          fileData:(NSData*)_fileData // contains target file data bytes
                        fileLength:(UInt32) _fileLenght // contains size of target file
{
  // result list of the (duplcate)files
  NSMutableArray* fileList = [[NSMutableArray alloc] init];
  
  @autoreleasepool {
    // flag to check if the path is a folder
    BOOL isDir;
    
    //stores the size of the file that is being itrated
    UInt32 size = 0;
    //stores the byte data of the file that is being itrated
    NSData *bytes = nil;
    
    //itrating the files in the list one by one in order find the duplicate
    for (NSString* sPath in fileCompareList) {
      //checking if the file already exists in the result list
      if ([fileList indexOfObject:sPath] == NSNotFound)
      {
        //getting the size of the file
        UInt32 size = [sysHelp getSizeOfFile:sPath];
        //if the size matches of the target file and the itrated file then go inside
        if(size == _fileLenght)
        {
          //get the bytes of the file being itrated
          bytes = [[NSData alloc] initWithContentsOfFile:sPath];
          
          //if the bytes matches then add the itrated file into the result list
          if([bytes isEqualToData:_fileData])
          {
            [fileList addObject:sPath];
          }
          //remove the itrated file data from the array
          bytes = nil;
        }
      }
      
    }
  }
  return fileList;
}

编辑:解释

有两种方法可以放弃对象的所有权。一种是释放,另一种是自动释放。如果您调用 release 到一个对象并且如果对象的保留计数变为它会立即释放,但如果您自动释放一个对象,则一旦自动释放池被释放/耗尽即发送释放消息即延迟释放。举个例子吧。

- (void)testMemoryInARC1 {
  NSData *data = [[NSData alloc] initWithContentsOfFile:@"myfile.mp3"]; // reatin count is 1
  //used this data an after few statements
  //statement 1
  // ..
  
  
  //at the end of data varibale scope in this case it's the end of method
  //ARC will insert the release call
  // [data rlease]; //wchich releases the memory
}


- (void)testMemoryInARC2 {
  NSData *data = [NSData dataWithContentsOfFile:@"myfile.mp3"]; // this method returns the autorelase object
  //used this data an after few statements
  //statement 1
  // ..
  
  
  //at the end of data varibale scope in this case it's the end of method
  //ARC will NOT insert the release call since that was autoreleased object
  //hence no release call
}

那么问题来了,什么时候发布?
ARS 说,“好问题,它会在自动释放池结束时释放(释放)”。

自动释放池何时结束?
ARC 说,“只需检查你在哪里创建了自动释放池,如果你还没有创建它,那么main.m 文件中有一个主自动释放池”

这意味着当 main 方法结束时所有的 autorelease 对象都被释放,这对我程序结束有什么帮助?
ARC 说:“又是一个好问题!Cocoa 库在整个开发过程中都使用了自动释放池,如果您没有使用它,那么先生,这是您的问题而不是我的问题。”

About Memory Management

【讨论】:

  • 它起作用了……它像魔法或魅力一样起作用……天哪!……拜托……它是如何起作用的????请详细说明
猜你喜欢
  • 1970-01-01
  • 2011-01-18
  • 1970-01-01
  • 2021-02-03
  • 1970-01-01
  • 2019-10-29
  • 1970-01-01
  • 1970-01-01
  • 2018-12-25
相关资源
最近更新 更多