Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Speicherauslastung senken (https://www.delphipraxis.net/156024-speicherauslastung-senken.html)

G-Baumstamm 17. Nov 2010 07:31

Delphi-Version: 7

Speicherauslastung senken
 
Joho,

habe eine Anwendung, die in mehreren gleichen Durchläufen Klicks auf dem Bildschirm ausführt. Hierzu ist nach einigen Klicks etwas Wartezeit eingebaut, entweder statisch über Sleep oder dynamisch über folgende Prozedur:

Delphi-Quellcode:
procedure Warten(x,y,Farbe: integer);
  var C: TCanvas;
      Count, Pixel: integer;
begin
  Count := 0;
  repeat
    if Count = 0 then C := TCanvas.Create;
    C.Handle := GetWindowDC(GetDesktopWindow);
    Pixel := GetPixel(C.Handle,x,y);
    inc(Count);
  until (Pixel = Farbe) or (Count = 1000);
  C.Free;
end;
Die Prozedur kontrolliert die übergebenen Koordinaten solange, bis der Pixel entweder die übergebene Farbe hat, oder die andere Abbruchbedingung erfüllt ist.

Diese Prozedur wird mehrfach an verschiedenen Stellen aufgerufen. Nach jedem Durchlauf habe ich testweise meine Speicherauslastung mit der hier beschriebenen Methode geprüft, und festgestellt das sie nach jedem Durchlauf um etwa 0,5 MB gestiegen ist. Es muss definitiv an dieser Schleife liegen, auch wenn ich alles andere auskommentiere tritt der Effekt auf. Warum? Ich erzeuge doch nur ein einziges mal ein Objekt, welches ich nachher auch immer wieder frei gebe?!

Was aber das eigentliche Problem ist: mit jedem Durchlauf nimmt die Geschwindigkeit ab, beim 1. und 2. gehts noch, aber beim 3. oder spätestens beim 4. werden die Aktionen deutlich langsamer ausgeführt. Die statischen Wartezeiten reichen dann oft nicht mehr, und das Programm verheddert sich. Aber hey, ich hab 4GB RAM, da können diese 0,5 MB doch keinen Unterschied machen?!

Hoffe jemand kann etwas gegen meine Verwirrung tun ... Danke ;)

Luckie 17. Nov 2010 07:43

AW: Speicherauslastung senken
 
Kein Wunder:
Delphi-Quellcode:
repeat
    if Count = 0 then C := TCanvas.Create;
    C.Handle := GetWindowDC(GetDesktopWindow);
    Pixel := GetPixel(C.Handle,x,y);
    inc(Count);
  until (Pixel = Farbe) or (Count = 1000);
  C.Free;
Du erstellst bei jedem Schleifendurchlauf einen Canvas und gibst nur einen hinter der Schleife wieder frei.

Klaus01 17. Nov 2010 07:50

AW: Speicherauslastung senken
 
Delphi-Quellcode:
procedure Warten(x,y,Farbe: integer);
  var C: TCanvas;
      Count, Pixel: integer;
begin
  Count := 0;
  c := TCanvas.Create;
  try
    repeat
      C.Handle := GetWindowDC(GetDesktopWindow);
      Pixel := GetPixel(C.Handle,x,y);
      inc(Count);
      ReleaseDC(c.Handle);
    until (Pixel = Farbe) or (Count = 1000);
  finally
    C.Free;
  end;
end;
Begründung:
Zitat:

The application must call the ReleaseDC function for each call to the GetWindowDC function and for each call to the GetDC function that retrieves a common DC.

An application cannot use the ReleaseDC function to release a DC that was created by calling the CreateDC function; instead, it must use the DeleteDC function. ReleaseDC must be called from the same thread that called GetDC.
Grüße
Klaus

Bummi 17. Nov 2010 07:54

AW: Speicherauslastung senken
 
ReleaseDC fehlt auch ...

Delphi-Quellcode:
begin
C := TCanvas.Create;
try
  C.Handle := GetWindowDC(GetDesktopWindow);
  try
    repeat
        Pixel := GetPixel(C.Handle,x,y);
        inc(Count);
    until (Pixel = Farbe) or (Count = 1000);
  finally
        ReleaseDC(C.Handle)
  end;
finally
  C.Free;
end;
end;

G-Baumstamm 17. Nov 2010 07:58

AW: Speicherauslastung senken
 
Au weia. Das dabei auch nen Objekt erzeugt wird wusste ich garnich ... manchmal ist Copy-Paste eben gefährlich, grade wenn der Code so unsauber is. ^^

Danke für deine Hilfe!

Wenn ich nen ReleaseDC einbaue gehts tatsächlich völlig flüssig ... warum ich trotz 4 GB RAM eine Mehrbelastung des Speichers von vlt 1,5 MB sofort spüre, verstehe ich aber trotzdem nicht ... ;)

Blup 22. Nov 2010 10:56

AW: Speicherauslastung senken
 
Der Speicherverbrauch dürfte auch nicht die direkte Ursache für den Geschwindigkeitsverlust sein.
Ohne "ReleaseDC" muss Windows immer mehr Gerätekontexte verwalten.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:09 Uhr.

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