我目前正在编写我的应用程序,该应用程序经常加载图像(但不是相同的图像)。据我测试,没有内存泄漏问题,但是随着我加载不同的图像,应用程序的内存使用量会增加。这意味着该应用程序最终会在达到内存上限时被操作系统杀死。我通过仪器检查,发现 NSConcreteData 占用了大量内存。
//from different thread, and pass data to main thread
NSData *data = [[[NSData alloc] initWithContentsOfURL:url] autorelease];
//at main, data to uiimage
imgView.image = [[[UIImage alloc] initWithData:data] autorelease];
当 View 被关闭并且所有分配的内存都返回到堆中时,似乎内存 我为 NSData 分配的内容保留在内存中,因此与加载图像之前相比,应用程序的内存使用量增加了。我不确定这是否是正常行为。 或者在不同线程之间传递分配的内存是不好的做法?
这可能对您的具体情况有所帮助,也可能无济于事,但通过密切关注您的自动释放堆栈增长通常可以减少这种情况。您应该能够通过将那些繁重的创建者(来自 url 的数据、带有数据的图像)包装在自动释放池 block 中来减少问题。
@autoreleasepool { work with large NSObjects here }
或者,取决于您必须部署的系统:
NSAutoreleasePool * pool = [NSAutoreleasePool new];
work with large NSObjects here
[pool release];
如果您可以使用 @autoreleasepool
,请这样做。它稍微好一点,因为它直接与底层自动释放堆栈接口(interface)。如果您需要向后兼容,请使用 NSAutoreleasePool
。在更高的层次上,它们确实服务于相同的目的,从某种意义上说,您应该能够在您的程序中交换它们的实现,而不会引入新的问题。因此,它实际上归结为您所针对的最低操作系统以及您在决定使用哪个时为您的项目指定的build设置。
您应该在自动释放 block 中处理和创建大(或许多)分配,因为自动释放的对象会“在未来的某个时间点”发送释放消息。通过显式创建和销毁该自动释放池(并且减少使用自动释放的频率),您可以更快地销毁其中的许多对象。
除了在你的程序中简单地不使用自动释放之外,为什么这样做会很好:客户端和系统库最终可能会将你的大/大量图像/NSData
添加到自动释放池中。自动释放池类似于(线程本地)堆栈——当您销毁本地池时,所有在您的池位于顶部时发出的自动释放消息都将得到满足,并且自动释放的对象将收到它们的释放消息。
Or is it bad practice to pass allocated memory between different threads?
请记住,您应该从主线程向您的 UIKit 和 AppKit 对象发送消息。在 Cocoa 中,许多库可以指定它们的线程模型。 NSData 遵循 Foundation 线程模型。这些对象不是明确的线程安全的,但如果您在任何给定时间从不超过一个线程读取和/或写入它们是安全的(也就是说,只要您需要在 MT 上下文中使用它,就使用锁,或者通过副本)。传递和共享数据/对象并不是一个坏习惯,有时它是必要的(或逻辑解决方案)。有一个小问题说它“不错”:很多人不太了解多线程和共享资源(对于许多人来说,学习这不是一项微不足道的技能)。
关于iphone频繁加载图片时如何管理内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7831534/
欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) | Powered by Discuz! X3.4 |