2016-04-12 12 views
4

誰かがSwiftのメモリ管理について明確にしてもらえますか?アプリケーションが起動した後Swiftのメモリ管理:NSOperation終了後にメモリが解放されない

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

が、私は3つの同期操作をエンキュー:

は、私は次のアプリデリゲートを持っています。各演算は非常に大きな文字列(構造体も含む)を持つ非常に大きな辞書(構造体)を作成するだけです。

作成されたデータはすべて値型で何もキャプチャされていないため、のメモリはメイン関数が終了するとにリリースされます。実際、メモリが解放されたことを確認するために、私はd.RemoveAll()を追加しました。

すべての操作は、アクティビティモニタを完了した後に情報を以下に示し: enter image description here

私のアプリケーションは、まだ26.7メガバイトを占めるが、私はすべての_queue.addOperation(Operation())を削除した場合は約7メガバイトだろう。すべての操作が完了したときに追加の19MBのメモリが解放されなかったのはなぜですか?

@Louフランコ 私はこの

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

にアプリのデリゲートを変更し、今8つの操作を同時に実行します。すべての操作が約40メガバイト完了した後にunreclaimed。私は100000操作をキューに入れようとしました。アプリは40分間クラッシュしないでください。メモリ使用量は600 ... 1000mbでしたが、すべての操作が完了するまで待つことができませんでした。

+0

私は漏れの機器でこれを確認します。このコンテキストのメモリがオブジェクトまたは予約されたページに割り当てられているかどうかは分かりません(後で回収される可能性があります) –

+0

計測器でリークは検出されません。また、メモリヒーププロファイリングでは、機器によって表示された25MBの代わりに9MBのみが永続的に残っていると述べています。私が理解しているように、システムが十分なメモリを持たず、私用メモリがアプリケーションが実際に使用しているものであるときに再利用できるものです。しかし、私は確かに分かりません。 –

+0

私はあなたが漏れを持っていないことを漏出計器が信じています。アクティビティモニターはそれを知りません - プロセスのために予約されているものを数えます - あなたはそれを直接制御することはできません。 Xcodeのデバッグナビゲータを使って、アプリケーションのメモリ使用量を簡単に確認することをお勧めします。 –

答えて

0

あなたは漏れていません。このプロセスでは、すぐにすべてのメモリがオペレーティングシステムに戻されるわけではありません。これは非常に無駄で高価なものになります。メモリはmalloc空きメモリリストに返されます。

テストコードの実行実際には、各操作が完了した後にメモリが上昇してからドロップされるのが見えます。

また、断片化されている場合(いくつかのオブジェクトがまだ空いているバイトの間に生きている)には、メモリがOSに返されないと思われます。あなたの例のこの変形は、操作が完了すると数百MBの最高水準点に達し、13.8に戻ります。連続したバッファを割り当てることで、OSに返す準備ができているチャンクがたくさんあることがわかります。

@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) 
     } 
    } 
} 
関連する問題