Speicherfreigabe wenn ein Fenster geschlossen wird

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

Macoun 2019 - Frühbucherrabatt bis 26.7.2019

  • Speicherfreigabe wenn ein Fenster geschlossen wird

    Hallo zusammen,

    ich bin gerade dabei mein Programm zu optimieren und schau mir dabei auch den Speicherverbrauch an. Dabei ist mir folgendes aufgefallen:

    Die Konfigurationseinstellungen meines Programms werden in einem separatem Fenster dargestellt. Dieses Fenster als auch der dazugehörige ViewController wird zur Laufzeit erzeugt. Damit die Ressourcen nicht gleich zu beginn verwendet werden, habe ich dies mittels Lazy-Variablen gelöst:

    Quellcode

    1. // MARK: - Konfiguration / Daten
    2. lazy var viewController_Config: ConfigViewController? =
    3. {
    4. let Storyboard : NSStoryboard? = NSStoryboard(name: NSStoryboard.Name("Config"), bundle: nil)
    5. var ConfigViewController = Storyboard?.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("ConfigViewController")) as! ConfigViewController?
    6. return ConfigViewController
    7. }()
    8. lazy var windowController_Config: ConfigWindowController? =
    9. {
    10. let Storyboard: NSStoryboard? = NSStoryboard(name: NSStoryboard.Name("Config"), bundle: nil)
    11. var ConfigWindowController = Storyboard?.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("ConfigWindowController")) as! ConfigWindowController?
    12. ConfigWindowController?.contentViewController = viewController_Config
    13. // Initialized-Variable setzen
    14. windowControllerConfigInitialized = true
    15. return ConfigWindowController
    16. }()
    Alles anzeigen

    Das Fenster selbst wird relativ simpel eingeblendet:

    Quellcode

    1. /// Blendet den Daten-Konfigurationsdialog ein
    2. func showDataConfig() {
    3. closeMainWindow()
    4. windowController_Config?.showWindow(self)
    5. }

    Wenn nun das Konfigurationsfenster aufgerufen wird steigt der Speicherverbrauch der Anwendung um ca. 150 MB an (es handelt sich um eine umfangreiche Konfiguration - u.a. mit TableViews, etc. - also sollte soweit passen). "Release when closed" im Storyboard ist gesetzt. Allerdings bleibt der Speicher belegt selbst wenn das Fenster wieder geschlossen wurde.

    Beim suchen nach der Ursache bin ich u.a. auf folgende Info gestoßen:

    stackoverflow schrieb:

    When you're using a window controller, you do not release the window itself. The window controller owns it and it will release it when it's done with it. Likewise, releaseWhenClosed is ignored for windows owned by window controllers.
    Anschließend habe ich versucht mittels CFGetRetainCount(windowManager.windowController_Config?.window) den Referenzzähler zu ermitteln. Dieser geht selbst beim schließen des Fensters nicht auf 0 (bleibt konstant bei 2).

    Meine Frage nun: wie kann ich sicherstellen, dass beim schließen eines Fensters einer Anwendung auch die dafür verwendeten Ressourcen wieder freigegeben werden (zumindest bis das Fenster - in meinem Fall der Konfigurationsdialog - wieder benötigt wird)?

    Falls jemand eine Idee oder Tipp hat würde ich mich über eine Antwort freuen
  • Mac & i Test Abo
  • gkoeder schrieb:

    Wenn nun das Konfigurationsfenster aufgerufen wird steigt der Speicherverbrauch der Anwendung um ca. 150 MB an (es handelt sich um eine umfangreiche Konfiguration - u.a. mit TableViews, etc. - also sollte soweit passen). "Release when closed" im Storyboard ist gesetzt. Allerdings bleibt der Speicher belegt selbst wenn das Fenster wieder geschlossen wurde.
    150 MB ist wohl nicht nur dein Konfigurationsdialog... Was passiert denn wenn Du den Konfigurationsdialog öffnest - schließt - öffnest - schließt usw. Wächst das weiter an? - Dann hast Du nämlich ein problem. Wenn das nur einmal passiert und das geteilter Speicher ist, dann passt das eigentlich.
  • Hi manoh,

    vielen Dank für Dein Feedback. Der Konfigurationsdialog ist ziemlich umfangreich (u.a. mit ner komplexen TableView) - der Speicherverbrauch kommt schon in etwa hin. Auf ein MemoryLeak habe ich das ganze bereits untersucht - da scheint alles zu passen. Vielleicht hör ich mit den 150 MB +/- auch sprichwörtlich "das Gras wachsen" - aber ich versuch eigentlich immer, Anwendungen soweit möglich ressourcensparend zu erstellen und da ist mir das aufgefallen.
    Die im verlinkten Artikel (siehe erster Post von mir) angesprochene Lösung mit einem Observer welcher schließlich das Fenster "hart" auf NIL setzt klingt mir irgendwie zu sehr nach einem Workaround (vor allen da es ja m.M. in das ARC-System eingreift).

    Nebenbei: Ich hab ja mittels CFGetRetainCount(windowManager.windowController_Config?.window) herausgefunden dass der Referenzzähler nicht auf 0 runtergeht. Gibt es hier generell eine Möglichkeit rauszufinden welche Objekte hier noch eine Referenz offenhalten? Das wäre zur Spurensuche ganz praktisch - allerdings hab ich dazu nichts finden können.