MoveItemAtPath 的内存峰值

Posted

技术标签:

【中文标题】MoveItemAtPath 的内存峰值【英文标题】:Memory spike with MoveItemAtPath 【发布时间】:2011-10-10 19:19:42 【问题描述】:

我正在使用照片选择器来浏览和选择一个视频,一旦选择了它,我就会将它从临时存储移动到我的工作目录以供将来使用。我使用以下行来执行此操作:

[[NSFileManager defaultManager] moveItemAtPath:newName toPath:newPath error:nil];

当我对应用程序进行分析时,在此过程中,内存使用量会飙升至视频文件的大小,然后稍后又回落。有没有办法在没有内存峰值的情况下移动这个文件?如果用户的设备当时运行了很多应用程序,我担心我的应用程序会崩溃。

如果它有助于我的路径如下所示: /private/var/mobile/Applications/046F9A22-DBEC-436F-936C-D59945783483/tmp//trim.PK4abv.MOV

/private/var/mobile/Applications/046F9A22-DBEC-436F-936C-D59945783483/Documents/resources/myCards/BC742DC8-A7D4-40B8-8AC8-97CF9F242881/trim.PK4abv.MOV

【问题讨论】:

【参考方案1】:

如果内存峰值与文件大小相当,则可能是将整个文件加载到内存中,如果文件大小变得非常大,这确实会导致问题。我处理这个问题的方法(复制/附加到文件时)是将文件分成小块移动,就像这样(好的旧 C 文件 API):

#import <sys/stat.h>

+(BOOL) moveFileAtPath:(NSString*)sourcePath 
          toFileAtPath:(NSString*)targetPath 
      inChunksWithSize:(size_t)bytes 

    // open target file for appending
    FILE *targetFile = fopen([targetPath UTF8String], "a");
    if(targetFile == NULL)
        return NO;

    FILE *sourceFile = fopen([sourcePath UTF8String], "rb");
    if(appendFile == NULL) 
        fclose(targetFile);
        return NO;
    

    void *data = malloc(bytes); 
    if (data == NULL) 
        fclose(targetFile);
        fclose(sourceFile);
        return NO;
    

    size_t sourceSize = (size_t)filelength(fileno(sourceFile));
    off_t currentOffset = 0;

    while (currentOffset < sourceSize) 
        fseeko(sourceFile, currentOffset, SEEK_SET);
        size_t read_bytes = fread(data, 1, bytes, sourceFile);
        fwrite(data, 1, read_bytes, targetFile);
        currentOffset += read_bytes;
        if (read_bytes < 1)
            break;
    

    free(data);
    fclose(targetFile);
    fclose(sourceFile);

    return YES;

【讨论】:

非常感谢!现在试试这个 如果您只是将现有文件从一个位置移动到另一个位置,这真的是大材小用。您可以只使用重命名()。当源和目标都在同一个卷上时,这就是 NSFileManager 应该做的,因此我的回答是。我很想知道您的应用程序的文件系统活动输出(带有回溯)。【参考方案2】:

您是否正在跨不同的卷“移动”?如果是这样,那么 NSFileManager 会将文件复制到目的地并删除原始文件。此副本可能会导致您的“内存峰值”。

【讨论】:

不,我正在从临时文件(选择它们时放置视频的位置)和我的应用程序文档文件夹中移动,这是在 iphone/ipad 顺便说一句

以上是关于MoveItemAtPath 的内存峰值的主要内容,如果未能解决你的问题,请参考以下文章

巨大的内存峰值 - CGContextDrawImage

如何获得python脚本的峰值内存使用量?

在没有内存峰值的情况下旋转 UIImage

VM:_UITextContainerView (CALayer) - 内存峰值

c# windows app - 分析峰值内存使用情况并识别趋势

如何测量当前 node.js 进程的峰值内存使用量