如何解决内存崩溃

Posted

技术标签:

【中文标题】如何解决内存崩溃【英文标题】:How to resolve memory crash 【发布时间】:2011-11-28 11:12:08 【问题描述】:

我正在创建一个具有多个动画的应用程序。 一共有 50 页,每一页都有不同的动画,每个动画使用许多图像。

我使用UIPresentModelViewController 来展示观点和 我正在使用NSTimer 更改图像。

当我连续滑动时,应用程序崩溃并显示此消息:-

Program received signal:  “0”.
Data Formatters temporarily unavailable, will re-try after a 'continue'. 

(Unknown error loading shared library "/Developer/usr/lib/libXcodeDebuggerSupport.dylib")

我搜索了很多,但找不到任何合适的解决方案。

【问题讨论】:

您是否尝试过运行“分析器”以查看是否发现任何潜在泄漏? @HansGruber:是的,我们尝试在内存泄漏的情况下运行,但我们没有发现任何泄漏。请提供任何其他解决方案..谢谢.. 分析器和泄漏是不同的工具。有一个静态 clang 分析器,您不仅可以使用它来查找内存泄漏,还可以查找代码中的其他问题点。定期运行它是个好主意。请注意,静态 clang 分析器不在仪器下运行,也不是分析工具。您将在“产品”菜单下找到它。 “产品 > 分析”。另一方面,Leaks 是一种分析工具,用于监视对象,以查看在删除对对象的所有引用后它们是否没有被释放。 发布更新图像的代码。您的泄漏可能会失控。另外,我假设您阅读了Data Formatters temporarily unavailable, will re-try after a 'continue'。那里的问题是由于内存泄漏造成的。 重申它可能存在某种内存泄漏。您是否正确地在视图上发布计时器?请记住,他们保留了他们的目标,所以如果你有一个未完成的计时器,它不仅会保留并可能泄漏,而且目标也会保留。这意味着您加载的每一个视图都不会消失。 【参考方案1】:

只需检查您的代码,每次都添加新视图但忘记释放它...

【讨论】:

感谢您的回答,但我们已经在 XIB 中使用了 IBOutlet 并相应地更改了其上的图像....请向我们提出更多建议..谢谢..【参考方案2】:

当您崩溃时,您需要查看(并且可能发布)堆栈跟踪。以及更改图像的代码。这听起来像是内存膨胀(不是真正的泄漏,因为有人仍在引用内存)。分析菜单项可能会捕获一些东西(您绝对应该运行它),但您可能需要运行分配工具并查看堆检查。请参阅http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/ 了解更多信息。

【讨论】:

【参考方案3】:

这对我来说听起来像是堆栈溢出。在项目的 C/C++ 语言设置的“其他 C 标志”部分中,为“-fstack-check”添加一个标志,看看是否会出现任何不需要的递归。

【讨论】:

【参考方案4】:

信号 0 通常是由于应用程序使用过多内存而导致内存不足。检查是否调用了内存警告方法。

数据格式化程序加载失败可能是因为没有足够的内存来加载它..

【讨论】:

这个答案是正确的,如果你得到一个信号 0,那么你就用完了所有可用的应用程序内存。您需要返回并重写您的代码,以便它不会同时将所有解压缩的图像保存在内存中。这是您内存不足的最可能原因,因为解压缩的图像非常大!【参考方案5】:

像你这样描述的 50 次观看听起来像是一个大记忆猪。所以我怀疑内存管理正在卸载一些视图。然后,当您的程序需要视图时,它们不存在并且您的程序崩溃。错误消息与此不太相符,但它可能无法准确地告诉您问题所在。

考虑以下可能的情况,看看它是否适合您编写此程序的方式。

为了让操作系统管理内存,它可以根据需要卸载视图并重新加载它们。完成后,将调用 viewDidUnload、loadView 和 viewDidLoad 方法。

viewDidUnload:

此方法被称为 viewDidLoad 方法的对应方法。当视图控制器需要释放其视图以及与该视图关联的任何对象以释放内存时,在内存不足的情况下调用它。因为视图控制器经常存储对视图和其他与视图相关的对象的引用,所以您应该使用这种方法来放弃这些对象的所有权,以便可以回收它们的内存。您应该只为以后可以轻松重新创建的对象执行此操作,无论是在您的 viewDidLoad 方法中还是从应用程序的其他部分。您不应使用此方法发布用户数据或任何其他无法轻松重新创建的信息。

加载视图:

视图控制器在请求视图属性但当前为 nil 时调用此方法。如果您手动创建视图,则必须覆盖此方法并使用它来创建视图。如果你使用 Interface Builder 创建你的视图并初始化视图控制器——也就是说,你使用 initWithNibName:bundle: 方法初始化视图,直接设置 nibName 和 nibBundle 属性,或者在 Interface Builder 中创建你的视图和视图控制器——那么你不能重写这个方法。

查看 UIView 类参考 --

viewDidLoad:

在视图控制器将其关联的视图加载到内存后调用此方法。无论视图是存储在 nib 文件中还是在 loadView 方法中以编程方式创建,都会调用此方法。此方法最常用于对从 nib 文件加载的视图执行额外的初始化步骤。

您可能无意中在您的 init 方法中而不是在您的 loadView 方法中初始化了这些视图。如果你这样做了,那么当操作系统卸载视图(你会看到 viewDidUnload 被调用)时,与视图相关的内存和所有子视图(所有图像和动画)将被卸载。这可以节省内存,但是当您需要重新显示其中一个已卸载的视图时,如果该视图之前已卸载,则将首先调用 loadView。如果您的视图设置是在 init 方法中而不是在 loadView 中完成的,则不会再次设置视图。但是如果视图设置是在 loadView 方法中完成的,它可以在内存管理卸载它后恢复。

【讨论】:

viewDidUnload 在 ios 6.0 中已弃用。在内存不足的情况下不再清除视图,因此永远不会调用此方法。【参考方案6】:

有一种简单的方法可以找出通过泄漏仪器等难以发现的泄漏 - 僵尸分析仪。它显示了程序中每个未链接的内存,您可以在几分钟内轻松检测泄漏并优化代码。

【讨论】:

【参考方案7】:

如果您在单个动画中使用大量图像,那么您做错了。您应该有一个或几个非常大的图像,然后只显示该图像的一部分。这样,您可以加载很少的图像,但具有与拥有许多图像相同的效果。

研究 cocos2d 或其他流行的游戏制作框架,因为它们比 UIKit 更有效地制作动画。

【讨论】:

【参考方案8】:

使用仪器工具找出内存崩溃的原因,然后使用推荐设计模式的最佳实践重构代码。对此没有唯一的解决方案。谢谢。

【讨论】:

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

如何通过karma和phantomjs来解决内存错误

如何解决sprintf参数类型错误导致程序崩溃

如何使用 oracle 集合解决内存问题?

云帮手在windows下提示虚拟内存不足,如何解决?

打开的网页经常崩溃怎么回事、

如何解决此 CollectionView 崩溃?