Autor Beitrag
dresado
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16



BeitragVerfasst: Mo 26.06.17 16:02 
Hallo miteinander,

ich habe das Problem, dass meine Anwendung sehr viel Arbeitsspeicher belegt, ohne diesen wieder frei zu geben.

Kurz zur Funktionsweise meines Programms:

Ich habe ein Panel in einem Hauptformular.
Dort werden UserControls eingeladen.
Beim Laden eines UserControls werden per DataAdapter Daten in ein DataSet geladen.
Die Daten benötige ich zum Anzeigen, Auswerten und Drucken.

Wenn ich jetzt das UserControl schließe (Panel.Controls[i].Clear()) und ein anderes UserControl in das Panel lade,
wird der Arbeitsspeicher nicht wieder frei gegeben, sondern weiter voll geschrieben.

Ich habe es schon mit umstellen auf Forms probiert.
GC.Collect() habe ich probiert, genau so wie DataSet.Dispose().


Ich hoffe Ihr könnt mir helfen.
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 26.06.17 16:37 
- Nachträglich durch die Entwickler-Ecke gelöscht -
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mo 26.06.17 16:47 
a.) Woher weißt du das Speicher nicht freigeben wird? Der Taskmanager ist da kein vertrauenswürdiges Tool. (Minimieren/Maximieren in Winforms ruft übrigens ebenfalls ein Collect auf das einen etwas glaubwürdigeres Bild im Taskmanager folgen läßt)
b.) Du solltest verfolgen ob deine Instanzen nicht mehr referenziert werden. Dispose hat ja nur bei unmanaged Resourcen eine Wirkung. Im Zweifel mit entsprechenden Memory Profilern prüfen. Man kann zum Beispiel vergessen Events abzuhängen. Wenn dein UserControl z.B. weiterhin ein Event der Form registriert wird das UserControl nicht freigegeben da ja die Form weiterhin auf deine Instanz (über seinen Delegaten) verweist.
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: Mo 26.06.17 17:50 
user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
a.) Woher weißt du das Speicher nicht freigeben wird? Der Taskmanager ist da kein vertrauenswürdiges Tool.


Welchem Programm kann man denn mehr vertrauen?

Vermutlich benutzt der Taskmanager - wie andere Programm seiner Art, vor allem der Process Explorer - auch "nur" irgendwelche (API-)Windows-Funktionen. Warum sollte es dann bei dieser Größe qualitative Unterschiede zwischen den Prozeßanzeigeprogrammen geben?
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mo 26.06.17 18:16 
Zitat:
Welchem Programm kann man denn mehr vertrauen?


Einem Profiler/Tool das den Speichermanager von .Net kennt. Bei geringem Anspruch zum Beispiel den CLR Profiler von Microsoft.
Das gleiche Problem hast du theoretisch ja auch bei Delphi und seinem MemoryManager(n). Nur das da das Diff von vor und nach dem MemoryManager wesentlich kleiner ist da Delphi deutlich systemnaher ist.

Zitat:
Warum sollte es dann bei dieser Größe qualitative Unterschiede zwischen den Prozeßanzeigeprogrammen geben?


Weil ein Prozes Speicher anfordern und halten kann ohne in gerade konkret zu brauchen sondern um Zugriffsoptimierung zu betreiben. Macht so ziemlich jede Umgebung mit einem speziellen Speichermanager. Umgebungen mit Garbage Collection wie .Net und Java halt so weitgehend das das was im Taskmanager gezeigt wird eben nicht aussreicht um zu sagen das man ein Problem hat. Es zeigt eventuell nur das ein Prozess gerade viel Speicher hält. Man sieht dort aber nicht das das eigentlich ungenutzer Speicher ist der von diesem Prozess sofort freigegeben werden würde wenn das System denn welchen woanders brauchen würde.


Zuletzt bearbeitet von Ralf Jansen am Mo 26.06.17 18:36, insgesamt 2-mal bearbeitet

Für diesen Beitrag haben gedankt: Delphi-Laie
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mo 26.06.17 18:19 
.NET verwaltet seinen Speicher (wegen des Garbage Collectors) selber - und gibt diesen nicht unbedingt sofort wieder an das Betriebssystem frei, s.a. Best Practices No. 5: Detecting .NET application memory leaks.
dresado Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16



BeitragVerfasst: Di 27.06.17 08:54 
Hallo miteinander,

vielen Dank für die schnellen Antworten.

UserControl.Dispose() habe ich schon ausgeführt. Das hat leider nichts gebracht.

Das der Taskmanager kein wirlich verlässliches Programm ist habe ich auch schon gelesen.
Beim Minimiren hat dieser aber das Freigeben des RAM angezeigt.

Ich habe jetzt aber heraus gefunden, dass ich vor dem Dispose des UserControls,
das mit Hilfe des DataAdapters gefüllte DataSet diposen und auf null setzten muss.
DataSet.Dispose() und DataSet = null.

Damit habe ich viel Arbeitsspeicher frei bekommen.
Jetzt suche ich nach weiteren Objekten.