Delphi-PRAXiS
Seite 3 von 5     123 45      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Speicherlast des Programms mittels GetMemoryManagerState - komischer Wert (https://www.delphipraxis.net/154621-speicherlast-des-programms-mittels-getmemorymanagerstate-komischer-wert.html)

t.roller 8. Nov 2016 14:53

AW: Speicherlast des Programms mittels GetMemoryManagerState - komischer Wert
 
How Much Memory Is Your Delphi Program Occupying?

Zacherl 8. Nov 2016 15:01

AW: Speicherlast des Programms mittels GetMemoryManagerState - komischer Wert
 
Zitat:

Zitat von t.roller (Beitrag 1353000)

Der Artikel ist nebenbei erwähnt inkorrekt. Memory Leaks kann man nicht zuverlässig über die WorkingSetSize detecten. Ich verweise auf folgenden Beitrag: http://stackoverflow.com/a/1986486. Die WorkingSetSize umfasst nämlich nur den Speicher des Prozesses, der momentan tatsächlich im physikalischen RAM in Verwendung ist. Grade bei Memory Leaks wird man auf die "vergessenen" Speicherstellen nie wieder zugreifen, weshalb Windows die betroffenen Pages früher oder später auslagert. Die WorkingSetSize verringert sich danach wieder um die ausgelagerte Datenmenge, das Memory Leak ist aber trotzdem vorhanden und verschwendet Platz im virtuellen Adressbereich.

Benmik 8. Nov 2016 17:25

AW: Speicherlast des Programms mittels GetMemoryManagerState - komischer Wert
 
Zitat:

Zitat von Zacherl (Beitrag 1353001)
Der Artikel ist nebenbei erwähnt inkorrekt.

Inkorrekt! INkorrekt !!! Wann habe ich das zum letzten Mal gelesen? Danach folgt aber "detecten"... Man weiß nicht mehr, was man denken soll.

Ich habe erstmal Benedikt Magnus' Anregung aufgegriffen und die Größe der 7 Bitmaps ermittelt:
Delphi-Quellcode:
SizeOf(BMP) + Bmp.Width * Bmp.Height * (24 div 8)
. Das ergab ungefähr 370 MB. Dann habe ich Bambinis Anregung umgesetzt, das ergab einen Wert von ca. 2,7 MB. Der Taskmanager zeigt ca. 500 MB. Das verstehe, wer will.

Die Umsetzung von Zacherls Hinweis wird etwas aufwändiger und dauern.

t.roller 8. Nov 2016 18:30

AW: Speicherlast des Programms mittels GetMemoryManagerState - komischer Wert
 
Zitat:

Zitat von Zacherl (Beitrag 1353001)
...Der Artikel ist nebenbei erwähnt inkorrekt. Memory Leaks kann man nicht zuverlässig über die WorkingSetSize detecten.

Was soll ich mit dieser Aussage anfangen?
Beispiel:
Wenn ich ein Auto habe mit im Fahrzeugschein eingetragener Länge von 4,00 Meter:
Ist das Auto 4,00 Meter lang oder ist es kürzer, weil ein LKW-Fahrer hinten draufgefahren ist?

Memory-Leaks sind nicht der Normalfall. Redet das niemanden ein!
MSDN verwendet auch die WorkingSetSize - was sonst.

In PSAPI.PAS:
Delphi-Quellcode:
  _PROCESS_MEMORY_COUNTERS = record
    cb: DWORD;
    PageFaultCount: DWORD;
    PeakWorkingSetSize: SIZE_T;
    WorkingSetSize: SIZE_T;
    QuotaPeakPagedPoolUsage: SIZE_T;
    QuotaPagedPoolUsage: SIZE_T;
    QuotaPeakNonPagedPoolUsage: SIZE_T;
    QuotaNonPagedPoolUsage: SIZE_T;
    PagefileUsage: SIZE_T;
    PeakPagefileUsage: SIZE_T;
  end;

Benedikt Magnus 8. Nov 2016 18:40

AW: Speicherlast des Programms mittels GetMemoryManagerState - komischer Wert
 
Zitat:

Zitat von Benmik (Beitrag 1353027)
Ich habe erstmal Benedikt Magnus' Anregung aufgegriffen und die Größe der 7 Bitmaps ermittelt:
Delphi-Quellcode:
SizeOf(BMP) + Bmp.Width * Bmp.Height * (24 div 8)
. Das ergab ungefähr 370 MB. Dann habe ich Bambinis Anregung umgesetzt, das ergab einen Wert von ca. 2,7 MB. Der Taskmanager zeigt ca. 500 MB. Das verstehe, wer will.

Bedenke, dass das Programm selbst ja auch noch Speicher braucht (plus evtl. Overhead). Außerdem wird Speicher, den das Programm einmal belegt hat, nicht unbedingt direkt wieder freigegeben.
Wenn du also eine Pauschale für das Programm selbst nimmst und dir merkst, wie viele MB an Bitmaps bisher maximal gleichzeitig im Speicher lagen, müsstest du etwas erhalten, dass garantiert unter dem Wert im Taskmanager liegt (und bei voller oder konstanter Auslastung an Bitmaps sogar nahe am Taskmanager).

Jim Carrey 8. Nov 2016 18:50

AW: Speicherlast des Programms mittels GetMemoryManagerState - komischer Wert
 
Zitat:

Zitat von Benedikt Magnus (Beitrag 1353037)
Außerdem wird Speicher, den das Programm einmal belegt hat, nicht unbedingt direkt wieder freigegeben.

Design Your Delphi Program in a Way That it Keeps its Memory Usage in Check

Zacherl 8. Nov 2016 19:05

AW: Speicherlast des Programms mittels GetMemoryManagerState - komischer Wert
 
Zitat:

Zitat von t.roller (Beitrag 1353034)
Zitat:

Zitat von Zacherl (Beitrag 1353001)
...Der Artikel ist nebenbei erwähnt inkorrekt. Memory Leaks kann man nicht zuverlässig über die WorkingSetSize detecten.

Was soll ich mit dieser Aussage anfangen?
[...]
Memory-Leaks sind nicht der Normalfall. Redet das niemanden ein!

Wo habe ich das denn behauptet? Ganz im Gegenteil sogar. Ich bezog mich ledigliech auf den von dir verlinkten Artikel, welcher mit diesem Satz beginnt:
Zitat:

No matter how much you try to code without bugs and memory leaks .. the more complex the application the more possible is to leak some memory.
Folglich impliziere ich, dass der danach gezeigte Code (welcher WorkingSetSize verwendet) dazu gedacht ist, Memory Leaks aufzuspüren. Das ist damit aber NICHT zuverlässig möglich (siehe den von mir verlinkten Stackoverflow Post). Stattdessen müsste PrivateBytes bzw. PagefileUsage verwendet werden.

Zitat:

Zitat von t.roller (Beitrag 1353034)

Die Relevanz dieses Beispiels sehe ich ebenfalls nicht. Hier wird einfach nur das komplette Struct gedumpt.

BUG 8. Nov 2016 19:20

AW: Speicherlast des Programms mittels GetMemoryManagerState - komischer Wert
 
Zitat:

Zitat von Jim Carrey (Beitrag 1353038)
Zitat:

Zitat von Benedikt Magnus (Beitrag 1353037)
Außerdem wird Speicher, den das Programm einmal belegt hat, nicht unbedingt direkt wieder freigegeben.

Design Your Delphi Program in a Way That it Keeps its Memory Usage in Check

Freigeben im Sinne von new/delete gibt Speicher wieder an den Memory-Manager zurück. Im Regelfall gibt der den Speicher aber nicht wieder an das Betriebssystem zurück, sondern behält ihn um zukünftige Anfragen zu erfüllen. Dass hängt natürlich von der Implementierung des MM ab, und häufig von der Größe der Anfragen. Wenn Seiten aus solchem Speicher eine Weile nicht benutzt werden, fallen sie eventuell aus dem Workingset und werden ausgepaged.

Zitat:

Zitat von Zacherl (Beitrag 1353043)
Folglich impliziere ich, dass der danach gezeigte Code (welcher WorkingSetSize verwendet) dazu gedacht ist, Memory Leaks aufzuspüren. Das ist damit aber NICHT zuverlässig möglich (siehe den von mir verlinkten Stackoverflow Post). Stattdessen müsste PrivateBytes bzw. PagefileUsage verwendet werden.

Korrekt. Die Größe des Workingsets ist eine Entscheidung des Betriebssystems.

Zacherl 8. Nov 2016 19:22

AW: Speicherlast des Programms mittels GetMemoryManagerState - komischer Wert
 
Der Punkt mit den Forms ist gut, aber mit MSDN-Library durchsuchenSetProcessWorkingSetSize die Pages zwangsweise auslagern zu wollen ist in meinen Augen großer Schwachsinn. Windows macht das nämlich ganz von alleine, wenn die betroffene Page einige Zeit lang nicht mehr verwendet wurde. Greift das Programm irgendwann wieder darauf zu, gibt es ein Page Fault und der Windows Memory Manager läd die Seite wieder in den RAM. Da sind im Hintergrund Algorithmen aktiv, die ziemlich gute Vorhersagen treffen.

Außerdem adressiert die diese API wieder nicht das eigentliche Problem. Also nochmal: Die großen Bitmaps erfordern große zusammenhängende Speicherblöcke im virtuellen Adressraum. Die Pages auszulagern entlastet aber nicht den virtuellen Adressraum, sondern nur den physikalischen Speicher.

Deshalb kann ich auch nur nochmal empfehlen die ganze Herangehensweise mit Messen des aktuell benutzten Speichers so schnell wie möglich zu vergessen. Man kann einfach nicht zuverlässig vorhersagen ab welcher Größe ein
Delphi-Quellcode:
EOutOfMemory
auftreten wird. Wie gesagt kann es sogar passieren, dass dein Prozess noch kaum Arbeitsspeicher verwendet, aber dank Fragmentierung kein genügend großer zusammenhängender Block verfügbar ist. Kannst du ganz leicht testen, indem du mal 1 GiB Speicher am Stück mit
Delphi-Quellcode:
GetMem
anforderst. Dieser Aufruf wird bei einem 32-Bit Programm in den meisten Fällen direkt scheitern. 1 GiB in mehreren kleinen 10 MiB Blöcken anzufordern, wird dahingegen sehr wahrscheinlich Erfolg haben. Auch wirst du merken, dass dein Bitmap Tool als 64-Bit Kompilat ohne Änderung vermutlich sehr viele Bitmaps mehr laden kann. Schlussfolgerung ist, dass nicht der physikalische RAM das Limit darstellt, sondern der virtuelle Adressraum.

Jim Carrey 8. Nov 2016 20:21

AW: Speicherlast des Programms mittels GetMemoryManagerState - komischer Wert
 
Das mit den Forms mache ich teilweise auch so. Ich erstelle komplexe Formulare erst wenn sie wirklich benötigt werden.
Das verschnellert den Programmstart und hält den Speicherverbrauch ein wenig niedriger.
Hat einzig den Nachteil der Usability im Sinne von "Wenn ich da drauf klicke, soll sofort was passieren" - ist dann eben nicht der Fall.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:05 Uhr.
Seite 3 von 5     123 45      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz