ios - Swift 中的内存管理 : memory don't released after NSOperation ends

标签 ios swift multithreading macos cocoa

有人可以澄清一件事关于 Swift 的内存管理吗?

我有以下应用委托(delegate):

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    private let _queue = NSOperationQueue()

    func applicationDidFinishLaunching(aNotification: NSNotification) {

        _queue.maxConcurrentOperationCount = 1

        _queue.addOperation(Operation())
        _queue.addOperation(Operation())
        _queue.addOperation(Operation())
    }
}

private class Operation: NSOperation {

    override func main() {

        autoreleasepool {

            var d = [String: AnyObject]()

            for i in 1...1000 {
                d[i.description] = Repeat(count: 10000, repeatedValue: "ABCDEF").joinWithSeparator("") // tested with repeat or just large string
            }

            d.removeAll()
        }
    }
}

应用程序启动后,我将三个同步操作加入队列。每个操作只创建非常大的字典(结构)和非常大的字符串(也是结构)。

由于所有创建的数据都是值类型并且没有捕获任何数据,我认为当 main 函数结束时内存应该被释放。事实上,我添加了 d.RemoveAll() 以防万一以确保释放内存。

所有操作完成后,Activity Monitor 显示以下信息: enter image description here

我的应用程序仍然占用 26.7mb 但如果我删除所有 _queue.addOperation(Operation()) 它将大约 7mb。为什么在所有操作完成后没有释放额外的 19mb 内存?

@娄佛朗哥 我将应用程序委托(delegate)更改为此

func applicationDidFinishLaunching(aNotification: NSNotification) {  
    for _ in 1...100 {
        _queue.addOperation(Operation())
    }
}

现在 8 个操作同时运行。所有操作完成后,大约有 40mb 未回收。我尝试对100000 个操作 进行排队。应用程序不会崩溃 40 分钟。它的内存使用量是 600...1000mb,但我没能等到所有操作都完成。

最佳答案

你没有泄漏。该进程不会立即将所有内存返回给操作系统 - 这将非常浪费和昂贵。内存返回到 malloc 空闲内存列表。

运行您的测试代码,我实际上看到内存在每次操作完成后先上升然后下降。

我还怀疑在碎片化的情况下内存不会返回给操作系统(一些对象在大量空闲字节之间仍然存在)。您的示例的这个变体达到了几百 MB 的高水位线,然后在操作完成时回落到 13.8。通过分配连续的缓冲区,我们知道将有大量大块准备返回给操作系统。

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    private let _queue = NSOperationQueue()

    func applicationDidFinishLaunching(aNotification: NSNotification) {

        _queue.maxConcurrentOperationCount = 1

        _queue.addOperation(Operation())
        _queue.addOperation(Operation())
        _queue.addOperation(Operation())
    }
}

private class Operation: NSOperation {

    override func main() {
        autoreleasepool {
            let count = 100000000
            let p = UnsafeMutablePointer<Int>.alloc(count)
            for i in 0..<count {
                p.advancedBy(i).initialize(i)
            }
            p.destroy(count)
            p.dealloc(count)
        }
    }
}

关于ios - Swift 中的内存管理 : memory don't released after NSOperation ends,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36574765/

相关文章:

java - 从不同线程更新 UI

ios - 使用 Swift 与需要 block 作为参数的 Objective C 方法进行交互

ios - 为什么 app delegate 应该为其他 viewController 中使用的属性创建实例?

ios - 根据某些条件 swift 执行同时操作

swift - 有些按钮可以工作,有些按钮即使在同一层次结构中也不能工作

Java线程存储

ios - "pod install"之后的重复目标

iphone - 减小 iOS 应用程序大小 - <imagename>@2x.png 图像是否多余?

ios - iOS 中的不同背景模式

c++ - 使用互斥量同步线程