Fyg*_*ygo 13 memory memory-leaks ios nsurlsession swift
所以我在与Swift的努力中遇到了另一个障碍.我正在尝试将多个图像加载到图像库中 - 除了一件事以外,一切正常.尽管我清除了图像,但应用程序的内存使用仍在不断增长和增长.在基本上消除了所有代码之后,我发现这是由我的图像加载脚本引起的:
func loadImageWithIndex(index: Int) {
let imageURL = promotions[index].imageURL
let url = NSURL(string: imageURL)!
let urlSession = NSURLSession.sharedSession()
let query = urlSession.downloadTaskWithURL(url, completionHandler: { location, response, error -> Void in
})
query.resume()
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,这段代码基本上没有任何功能.然而,每次我调用它,我的应用程序内存使用量都在增长.如果我注释掉查询,则内存使用量不会改变.
我已经阅读了几个类似的问题,但他们都涉及使用委托.那么,在这种情况下,没有委托,但存在内存问题.有人知道如何消除它以及导致它的原因吗?
编辑:这是一个完整的测试类.似乎只有在可以加载图像时内存才会增长,就像指向图像的指针永远保存在内存中一样.当找不到图像时,没有任何反应,内存使用率保持低水平.也许有些暗示如何清理这些指针?
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
//memory usage: approx. 23MB with 1 load according to the debug navigator
//loadImage()
//memory usage approx 130MB with the cycle below according to the debug navigator
for i in 1...50 {
loadImage()
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func loadImage() {
let imageURL = "http://mama-beach.com/mama2/wp-content/uploads/2013/07/photodune-4088822-beauty-beach-and-limestone-rocks-l.jpg" //random image from the internet
let url = NSURL(string: imageURL)!
let urlSession = NSURLSession.sharedSession()
let query = urlSession.downloadTaskWithURL(url, completionHandler: { location, response, error -> Void in
//there is nothing in here
})
query.resume()
}
}
Run Code Online (Sandbox Code Playgroud)
对不起,我还不知道如何使用探查器(在整个iOS爵士乐中非常棒),至少我会附上上面代码生成的探查器截图:

Com*_*ast 29
首先,你必须打电话invalidateAndCancel或finishTasksAndInvalidate在会议上......否则,繁荣,内存泄漏.
Apple的NSURLSession类参考在边框中的管理会话部分中说明:
重要信息---会话对象保留对代理的强引用,直到您的应用程序退出或显式使会话无效为止.如果您没有使会话无效,那么您的应用程序会在内存泄漏之前泄漏内存.
是的.
您可能还会考虑以下两种方法:
将cookie和凭据刷新到磁盘,清除瞬态缓存,并确保将来的请求发生在新的TCP连接上.
清空所有cookie,缓存和凭证存储,删除磁盘文件,将正在进行的下载刷新到磁盘,并确保将来的请求发生在新套接字上.
......直接引用上述NSURLSession类参考.
我还应该注意你的会话配置会产生影响:
- (void)setupSession {
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
config.URLCache = nil;
config.timeoutIntervalForRequest = 20.0;
config.URLCredentialStorage = nil;
config.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
self.defaultSession = [NSURLSession sessionWithConfiguration:config];
config = nil;
}
Run Code Online (Sandbox Code Playgroud)
如果您不使用[NSURLSession sharedSession]单例,那么一个键就是拥有自己的自定义单例NSObject子类,该子类具有会话作为属性.这样,您的会话对象就会被重用.每个会话都会创建一个与您的应用相关联的SSL缓存,需要10分钟才能清除,如果您为每个请求的新会话分配新内存,那么无论是否持续10分钟,您都会看到SSL缓存的无限内存增长或不是你invalidateAndCancel或冲洗/重置会话.
这是因为安全框架私有地管理SSL缓存,但是为你的应用程序收取它锁定的内存的费用.无论您是否将配置URLCache属性设置为nil,都会发生这种情况.
例如,如果您习惯于说,每秒100个不同的Web请求,并且每个请求使用一个新的NSURLSession对象,那么您每秒创建400k的SSL缓存.(我观察到每个新会话都负责appx.4k的安全框架分配.)10分钟后,这是234兆字节!
因此,请从Apple获取提示并使用具有NSURLSession属性的单例.
请注意,backgroundSessionConfiguration类型保存此SSL缓存的原因以及所有其他缓存内存(如NSURLCache)是因为backgroundSession将其处理委托给现在进行会话的系统,而不是您的应用程序,因此即使您的应用程序是没跑 所以它只是隐藏在你身上......但它就在那里......所以如果那里有巨大的内存增长(即使乐器不会向它显示),我也不会把它放在Apple之外拒绝你的应用程序或终止它的后台会话你,我打赌他们可以看到它).
Apple的文档称backgroundSessionConfigurationURLCache的默认值为零,而不仅仅是零容量.因此,尝试一个短暂的会话或默认会话,然后将其URLCache属性设置为nil,如上例所示.
NSURLRequestReloadIgnoringLocalCacheData如果您不打算使用缓存,那么将NSURLRequest对象的cachePolicy属性设置为也可能是个好主意:D
我在最近的应用程序中遇到了类似的问题.
在我的情况下,我从API下载了许多图像.对于每个图像,我创建了一个NSURLSessionDownloadTask并将其添加到具有临时配置的NSURLSession.任务完成后,我调用了一个完成块来处理下载的数据.
我添加的每个下载任务都会导致额外的内存(根据Xcode调试器)在之后的任何时候都没有释放.下载大约100张图像时,调试器的内存使用量为~600 MB.下载任务越多,分配和未释放的内存就越多.在任何时候我都没有以任何方式显示或使用图像数据,它只是存储在磁盘上.
试图在仪器中诊断问题并不富有成效.仪器没有泄漏,也没有与下载任务或图像数据相对应的分配.由于我的块等中的保留周期没有内存泄漏,只有在调试器中才有内存螺旋.
经过几个小时的试验和错误,包括:
在完成块设置为nil的情况下下载图像(以确保块中没有保留周期).
注释掉我的代码的各个部分,以确保在调用'[downloadTask resume]'时精确地进行分配.
将会话的URLCache设置为nil和大小为0的缓存.根据:http://www.drdobbs.com/architecture-and-design/memory-leaks-in-ios-7/240168600
将NSURLSession配置更改为默认配置.
最后,我将NSURLSession配置从短暂类型切换为背景类型.这要求我不使用完成块来处理图像.我改为在委托中处理它们.这解决了我的问题.将下载任务添加到后台NSURLSession导致内存增长几乎为零,因为下载已启动并处理.
我希望我能更好地理解为什么会这样,但遗憾的是我没有.我已经看到这个问题也出现在其他人身上,并且还没有找到更好的解决方案或解释.
| 归档时间: |
|
| 查看次数: |
8596 次 |
| 最近记录: |