2010-02-26 33 views
2

我正在运行一些内存分析为我的应用程序在SDK 3.2中,我用'泄漏'探查器找到我所有的内存泄漏,我把它们全部插上。这是一个scrollView导航控制器应用程序,其中有瓷砖,并且您可以单击一个瓷砖,然后转到新的瓷砖视图等等,我可以深入多层并回到顶部,并且“泄漏”分析器说明所有事物很酷。但是,如果我在'ObjectAlloc'分析器中观察内存占用情况,内存占用会随着我越来越深(这看起来合理)而变得越来越高,但是当我退出视图时,内存占用不会减少正如我所料。内存泄漏工具告诉我零泄漏,但内存占用不断上升

我知道这是应用程序的模糊描述,但我不能准确地发布数百行代码:)此外,应该指出的是,我使用coreData来存储图像数据,因为数据库正在增长在选择更多节点时的大小,不知道是否/何时从内存释放。

什么给?

回答

1

核心的数据存储管理的信息是良好的信息和技术上的答案通过亚瑟Kalliokoski是一个很好的答案:韭菜和对象分配之间的区别。我在这里遇到的一个特殊问题与模拟器中一个按钮上的setBackgroundImage显然已知的错误有关,它会产生内存“泄漏”,因为它不会释放释放UIImage的内存。

3

根据你在核心数据中构建的对象图的方式,它的内存使用可能会意外增长。

一个常见的错误是将对象存储在一个复杂且经常出现故障(加载到内存中)的实体中。这导致在实体的任何其他部分被引用时,大块被加载/保留在内存中。随着对象图形的增长,它会消耗越来越多的内存,除非您主动删除对象并保存图形。

例如:您的个人实体包含大量文本信息,例如名称,地址等以及一张大照片。如果您将照片设置为个人实体的属性,则只要个人实体出现故障,它就会记忆在内存中。如果您获得属性名称,那么photo属性也在内存中。

为了避免这种情况,blob应该在自己的实体中,然后链接到关系中的其他实体。由于关系对象在被直接调用之前不会发生故障,所以直到需要时它们才会保持内存不足。

+0

我在我的对象图中做了这一点,所有图像都有自己的实体。但是,如果我向coreData添加了大量新项目(包括图像),由于我刚刚添加了图像数据,因此图像数据在内存中,我如何“删除”某些内容以从内存中删除实体? – Shizam 2010-02-26 04:38:55

+0

找到'重新断层'的条目,给它一个去。 – Shizam 2010-02-26 04:53:57

+0

不知道这是否适用于您的应用,如果确实如此,您可能已经覆盖了该应用,但您只需在全尺寸图片上加载全尺寸图片即可。例如。一个tableview将在一个单元格的缩略图中显示一个完整大小的图像。它外表看起来很小但记忆明智,它非常巨大。如果可能的话,您应该创建并存储缩略图,这些缩略图的实际大小只有足够的分辨率。然后只将完整图像加载到需要的地方,然后立即处理它们。 – TechZen 2010-02-26 16:57:07

0

你可以有一个不断增长的程序,而不必泄漏内存。假设您从输入中读取单词并将它们存储在链接列表中动态分配的内存块中。当你阅读更多的单词时,列表不断增长,但所有内存仍然可以通过列表访问,所以没有内存泄漏。

1

仅仅因为没有基于refcount的泄漏,并不意味着你没有在字典“缓存”中填充某些东西并忘记它;那些不会显示为泄漏,因为它有有效的引用(该字典仍然有效,所有其子的引用也是如此)。你还需要寻找有效但不必要的对象。

最简单的方法是让它运行太久,然后按类型对对象计数进行排序,看看谁有一个巨大的数字 - 然后追踪参考图(在Obj-C中可能很难)。如果Instruments不直接执行此操作,则可以编写一个DTrace脚本来执行此操作。

1

重申:

char *str1 = malloc(1000); 
char *str2 = malloc(1000); 
    . 
    . 
    . 
char *str1000 = malloc(1000); 

是不是内存泄漏,但

char *str1 = malloc(1000); 
char *str1 = malloc(1000); //Note! No free(str1) in between! 

内存泄漏

+0

谢谢,我明白这一点。我的问题在于我创建子视图(并观察内存增加),然后正确释放所有视图(但内存占用不会减少)。我越想越多,我认为它与向coreData添加新信息有关。 – Shizam 2010-02-26 04:41:47

4

这听起来像它可能是几件事情之一:

  • 内存释放后不还给操作系统。这是C运行时的通用设计。当您执行分配时,C运行时会为其使用分配更多内存,并返回一大块内存供您使用。当你做一个空闲的时候,C运行时只是将它标记为释放,但不会将它返回给操作系统。因此,如果泄漏工具正在读取OS级统计信息而不是C运行时统计信息,那么泄漏工具将无法报告内存使用情况的相应减少。

  • 泄漏工具内存报告的误导值。泄漏工具可能会看到与C运行时不同的值,并报告的值会导致您担心,即使没有任何错误(就像人们试图在Windows中使用任务管理器来检测泄漏并因结果混淆一样)对于这项工作确实是一个非常糟糕的工具)。

  • 碎片化。您的应用程序可能遭受内存碎片。这是当你分配,然后释放然后分配,后续尝试分配大于释放留下的“漏洞”。发生这种情况时,会分割内存空间,留下不可用的空洞,从而阻止大量连续的内存块,并强制使用越来越多的内存空间,直到内存不足。这是一种病理状况,修复通常是特定于应用程序的。

我认为这三个建议中的第一个很可能是发生了什么事情。