应用程序在内存不足后关闭。仪器截图里面

Posted

技术标签:

【中文标题】应用程序在内存不足后关闭。仪器截图里面【英文标题】:App closes after running out of memory. Instruments screenshot inside 【发布时间】:2012-09-17 12:05:02 【问题描述】:

这是我通过仪器运行我的应用程序时得到的。它正在处理大量核心数据。我可以看到这显然是不对的,但我真的不知道这个屏幕截图告诉我什么。似乎是什么问题?如果您有兴趣,浓缩后的代码是这样的:

    NSFetchRequest *oldFetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *oldEntryEntity = [NSEntityDescription entityForName:@"Entry"
                                                      inManagedObjectContext:oldContext];

    [oldFetchRequest setEntity:oldEntryEntity];

    int numberOfEntries = [oldContext countForFetchRequest:oldFetchRequest error:nil];

    int batchSize = 4;
    [oldFetchRequest setFetchLimit:batchSize];
    int offset = 0;

    while (numberOfEntries - offset > 0) 
        @autoreleasepool 
        [oldFetchRequest setFetchOffset:offset];
        NSError *error;
        NSArray *entries = [oldContext executeFetchRequest:oldFetchRequest error:&error];

        for (NSManagedObject *entry in entries) 
        @autoreleasepool 
            Entry *newEntry = [NSEntityDescription insertNewObjectForEntityForName:@"Entry"
                                                            inManagedObjectContext:newContext];

            newEntry.entryID = [entry valueForKey:@"entryID"];

            NSMutableOrderedSet *newMediaSet = [[NSMutableOrderedSet alloc] init];

            NSOrderedSet *mediaSet = [entry valueForKey:@"media"];

            int i = 0;

            for (NSManagedObject *media in mediaSet) 

                Media *newMedia = [NSEntityDescription insertNewObjectForEntityForName:@"Media"
                                                                inManagedObjectContext:newContext];

                newMedia.isInPhotoLibrary = [media valueForKey:@"isInPhotoLibrary"];
                newMedia.positionInEntry = [NSNumber numberWithDouble:i + 1];

                MediaImageData *imageData = [NSEntityDescription insertNewObjectForEntityForName:@"MediaImageData"
                                                                          inManagedObjectContext:newContext];

                imageData.data = [media valueForKey:@"originalImage"];

                newMedia.imageData = imageData;

                newMedia.entry = newEntry;
                [newMediaSet addObject:newMedia];

                i++;
            

            newEntry.media = newMediaSet;


        
        

        [newContext save:&error];

        offset = offset + batchSize;
   

编辑:我按照这里给出的建议,将它包装在@autoreleasepools(我已经在上面编辑过)中,发生这种情况后它仍然崩溃:

它显然比第一次更深入代码,但它仍然崩溃。

【问题讨论】:

不要删除重要的代码。然后我们必须猜测正在发生的事情。您的获取请求甚至没有正确设置。另外,我看不到您在哪里添加了自动释放池...您的数据库有多大?您的媒体集及其包含的图像有多大?你在任何地方都抓着物体吗?您是否完全清除了上下文? 我现在已经放入了自动释放池。媒体集中的图像是标准图像的大小,我猜每个大约 1mb,具体取决于照片。在上面的代码之外,我没有做任何与此相关的事情。我没有清除上下文。 【参考方案1】:

不讨论代码的效率: 将您的代码包装在 @autoreleasepool 中,用于外部 (while) 和内部 (for) 循环。 否则,您只是分配大量内存并仅在外部事件循环到达其循环结束时释放它。

【讨论】:

谢谢,我试试看。你能讨论我的代码的效率吗?我很想知道如何才能做得更好。【参考方案2】:

尝试将快速枚举(for 循环)的内部包裹在@autoreleasepool 中,这应该会有所帮助。当更改达到危险的内存消耗时,您还可以运行某种计数器以将上下文保存在循环中。

你确实有很多对象,考虑优化你的数据结构。

【讨论】:

【参考方案3】:

首先,关于发布 Core Data 相关问题的一些建议。几乎没有太多的信息。当您省略细节时,人们很难为您提供帮助,因为可能的互动太多了。

仅查看您发布的代码,就会留下很多问题。

我希望查看按总体大小排序的信息,而不是按分配数量排序的信息。这将更容易地告诉您内存在哪里使用。实际上,我看不到那张图片中的内存在哪里使用(然后再次 - 老眼睛 - 当我放大它时,它变得太模糊了)。

如果您认为它与核心数据有关,为什么不运行核心数据工具?

关于一些诊断帮助。

您的新 MOC 是直接连接到 PSC 还是有父 MOC。如果它有一个父 MOC,那么保存只是被推送到父 MOC 中,并且会一直保留在内存中,直到保存被持久化到数据库中。

您的 mediaSet 中有多少项?可能有很多这些,这可能会占用内存。

您对 FetchRequest 和 MOC 应用了哪些参数?基于这些选项,MOC 可以保留对象。检查这一点的一种方法是记录每个 MOC 的保留/插入/删除/等集的计数。通过记录这些,您可以查看任何一个 MOC 是否持有您认为不应该持有的东西。

然后您就可以知道是否需要刷新/重置您的 MOC。

您可以作弊,并在保存后致电[moc reset],但最好能看到这样做之前/之后的数字,这样您就可以说服自己记忆在哪里。

做更多的调试。为自己提供更多信息,以便您做出正确的决定……它也会为我们提供更好的信息来帮助您。

编辑

哎呀。我删除了关于可能没有太多内存的 cmets。看着那张照片上的小字,我的老眼睛对我毫无帮助。

编辑

谢谢。如何记录保留/插入/删除集的计数 对于每个 MOC? ——安德鲁

MOC 有几个属性(registeredObjectsinsertedObjectsdeletedObjectsupdatedObjects)提供一组与这些类别匹配的对象。只需NSLog 每个类别中的对象数。您可以看到,对于每个 MOC,MOC 在一段时间内跟踪了多少对象。

另外,启用核心数据工具。它们的信息量很大。

【讨论】:

谢谢。如何记录每个 MOC 的保留/插入/删除集的计数?

以上是关于应用程序在内存不足后关闭。仪器截图里面的主要内容,如果未能解决你的问题,请参考以下文章

使用仪器解决内存不足警告

内存不足,仪器分配

虚拟内存地址空间不足(Borland C++ Builder 6 程序)

java内存不足怎么办

Instruments 指出内存不足警告,但内存使用率非常低

Out of Memory ——pycharm内存不足造成软件卡爆