Gestión de memory en Swift: la memory no se libera después de que termina NSOperation

¿Alguien podría aclarar algo sobre la gestión de la memory de Swift?

Tengo el siguiente delegado de la aplicación:

@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() } } } 

Después de que comenzó la aplicación, encojo tres operaciones síncronas. Cada operación solo crea un dictionary muy grande (struct) con cadenas muy grandes (también estructuras).

Como todos los datos creados son de tipo de valor y no se capturó nada, creo que la memory debería liberarse cuando termine la function principal. De hecho, agregué d.RemoveAll() si acaso para estar seguro de que la memory se soltó.

Después de todas las operaciones completadas, Activity Monitor muestra la siguiente información: introduzca la descripción de la imagen aquí

Mi aplicación todavía ocupa 26.7mb, pero si _queue.addOperation(Operation()) todo _queue.addOperation(Operation()) sería alnetworkingedor de 7mb . ¿Por qué no se liberaron 19 MB adicionales de memory cuando se completaron todas las operaciones?

@Lou Franco Cambié el delegado de la aplicación a este

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

Y ahora 8 operaciones se ejecutan simultáneamente. Después de que todas las operaciones finalizaron, 40 millones de libras quedaron sin reclamar. Traté de queue 100000 operaciones . La aplicación no falla durante 40 minutos. Su uso de memory fue de 600 … 1000mb , pero no pude esperar hasta que todas las operaciones se hayan completado.

No tienes fugas El process no devuelve inmediatamente toda la memory al sistema operativo; eso sería muy derrochador y costoso. La memory se devuelve a la list de memory libre malloc .

Ejecución de su código de testing En realidad, veo la escalada de la memory y luego suelto después de que cada operación se complete.

También sospecho que la memory no se devuelve al sistema operativo en los casos en que está fragmentada (algunos objects todavía están vivos entre muchos bytes libres). Esta variante de su ejemplo alcanza una marca alta de varios cientos de MB y luego vuelve a 13.8 cuando se completan las operaciones. Al asignar buffers contiguos, sabemos que habrá muchos trozos grandes listos para ser devueltos al sistema operativo.

 @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) } } } 
    Intereting Posts