Delphi-PRAXiS
Seite 1 von 5  1 23     Letzte » 

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)

moelski 18. Sep 2010 07:40

Speicherlast des Programms mittels GetMemoryManagerState - komischer Wert
 
Moin !

Wenn ich hiermit versuche die Speicherlast meiner Anwendung auszugeben ...
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
var State: TMemoryManagerState;
    Size, i : Cardinal;
begin
  GetMemoryManagerState(State);
    Size := 0;
    for i := 0 to High(State.SmallBlockTypeStates) do
      Inc(Size, State.SmallBlockTypeStates[i].AllocatedBlockCount *
              State.SmallBlockTypeStates[i].UseableBlockSize);
    Inc(Size, State.TotalAllocatedMediumBlockSize +
              State.TotalAllocatedLargeBlockSize);

  Form1.Caption := 'Item Assign Test - ' +
                   IntToStr(Size) + ' Memusage';
end;
Dann kriege ich als Wert ~100780.

Nur was sagt mir dieser Wert? 100kb Speicher den meine Anwendung nutzt?!
Der Taskmanager sagt nämlich was von 3,8MB ...

Sir Rufo 18. Sep 2010 09:56

AW: Speicherlast des Programms mittels GetMemoryManagerState - komischer Wert
 
Versuch es mal so:
Delphi-Quellcode:
function GetMemoryReserved : Cardinal;
  var
    State : TMemoryManagerState;
    idx : Integer;
  begin
    Result := 0;
    GetMemoryManagerState( State );
    for idx := low( State.SmallBlockTypeStates ) to high( State.SmallBlockTypeStates ) do
      Result := Result + State.SmallBlockTypeStates[ idx ].ReservedAddressSpace;
    Result := Result + State.ReservedMediumBlockAddressSpace + State.ReservedLargeBlockAddressSpace;
  end;
Dem System ist es schnurzpiepe, was du an Speicher tatsächlich belegst.
Es zählt was du reservierst (auf welcher Liege liegt dein Handtuch), denn das ist für das System auch nicht mehr nutzbar und gilt somit als belegt/benutzt.

Benmik 7. Nov 2016 19:16

AW: Speicherlast des Programms mittels GetMemoryManagerState - komischer Wert
 
Wenn ich diese Leiche nochmal exhumieren darf: Wenn ich mit diesem Code messe, erhalte ich einen Wert von 5.000.000, während der Taskmanager mir 500.000.000 anzeigt. Was läuft da schief?

Hintergrund ist, dass ich eine variable Anzahl von Bitmaps (aus JPG) in den Speicher vorlade. Sind die Bitmaps sehr groß, gibt es eine EOutOfMemory. Ich würde das gern vorher wissen und vermeiden. Laut Taskmanager-Anzeigen ist bei ca. 1,8 GB Schluss. Wie messe ich das jetzt, was wäre ein Schwellenwert, der nicht überschritten werden sollte (den theoretischen Wert von 2 GB bei einer 32 Bit-Anwendung kenne ich natürlich)?

Jim Carrey 7. Nov 2016 19:46

AW: Speicherlast des Programms mittels GetMemoryManagerState - komischer Wert
 
Nur zum Test!
Setze mal folgendes in deine DPR-Datei relativ an den Anfang und mache deinen Test mit den Bildern noch einmal:
Delphi-Quellcode:
//

{$SETPEFLAGS IMAGE_FILE_LARGE_ADDRESS_AWARE}

//
Damit solltest von von 2 GB auf etwa 3 GB maximalen Verbrauch kommen können.

Benmik 7. Nov 2016 20:00

AW: Speicherlast des Programms mittels GetMemoryManagerState - komischer Wert
 
Das führt leider nicht weiter. Selbst wenn es funktionierte, käme die Speichererschöpfung halt nur etwas später. Es erklärt auch nicht, warum Sir Rufos Code nicht zu funktionieren scheint.

Jim Carrey 7. Nov 2016 21:33

AW: Speicherlast des Programms mittels GetMemoryManagerState - komischer Wert
 
Guck mal hier:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
 function GetCurrentProcessMemorySize: Int64;
 var
  nWndHandle, nProcID, nTmpHandle: HWND;
  pPMC: PPROCESS_MEMORY_COUNTERS;
  pPMCSize: Cardinal;
 begin
  nWndHandle := Application.Handle;
  if nWndHandle = 0 then
   begin
    Result := 0;
    Exit;
   end;
  pPMCSize := SizeOf(PROCESS_MEMORY_COUNTERS);
  GetMem(pPMC, pPMCSize);
  pPMC^.cb := pPMCSize;
  GetWindowThreadProcessId(nWndHandle, @nProcID);
  nTmpHandle := OpenProcess(PROCESS_ALL_ACCESS, False, nProcID);
  if (GetProcessMemoryInfo(nTmpHandle, pPMC, pPMCSize)) then
   Result := pPMC^.WorkingSetSize
  else
   Result := 0;
  FreeMem(pPMC);
  CloseHandle(nTmpHandle);
 end;

begin
 ShowMessage(IntToStr(GetCurrentProcessMemorySize)));
end;
Das zeigt den Arbeitssatz an.

Quelle: http://snipplr.com/view/38214/get-process-memory-usage/

Benmik 7. Nov 2016 21:39

AW: Speicherlast des Programms mittels GetMemoryManagerState - komischer Wert
 
Wirklich vielen Dank für deine Mühe, Jim, aber das zeigt - wenn ich mich nicht irre - nur den Speicherverbrauch des laufenden Prozesses an. EOutOfMemory kommt aber bei der Gesamtgrenze für das ganze Programm.

Jim Carrey 7. Nov 2016 21:43

AW: Speicherlast des Programms mittels GetMemoryManagerState - komischer Wert
 
Ich dachte du suchst eine Funktion die den Speicherverbrauch anzeigt? :pale:

Das mit dem OutOfMemory... wieso fängst du den nicht ab und wenn er auftritt, brichst du die aktuelle Funktion ab?

Delphi-Quellcode:
for i := 0 to 100 do
 begin
  try
   tueirgendetwas;
  except
   on E: EOutOfMemory // <===========
    begin // <===========
     Break; // <===========
    end; // <===========
  end;
 end;
Ich weiß nicht, ob man das so macht, aber was anderes fällt mir nicht ein.

Zacherl 7. Nov 2016 22:21

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

Zitat von Jim Carrey (Beitrag 1352927)
Guck mal hier:

Wer auch immer diesen Code verbrochen hat, hat absolut keine Ahnung von der Win32 API. Den ganzen Quatsch mit MSDN-Library durchsuchenGetWindowThreadProcessId und MSDN-Library durchsuchenOpenProcess kann man sich sparen und stattdessen einfach MSDN-Library durchsuchenGetCurrentProcess bzw.
Delphi-Quellcode:
THandle(-1)
an MSDN-Library durchsuchenGetProcessMemoryInfo übergeben.

Zitat:

Zitat von Benmik (Beitrag 1352928)
Wirklich vielen Dank für deine Mühe, Jim, aber das zeigt - wenn ich mich nicht irre - nur den Speicherverbrauch des laufenden Prozesses an. EOutOfMemory kommt aber bei der Gesamtgrenze für das ganze Programm.

Diese Aussage verstehe ich nicht ganz. Eine feste Obergrenze gibt es nicht. Mit der 2 GiB Grenze für 32-Bit Prozesse hast du zwar recht, allerdings reservierst du (oder die Delphi RTL, oder Funktionen, die du verwendest) ja mehr oder weniger unvorhersehbar noch Speicher in Form von Objekten, Strings, Arrays, etc.
Dann kommt noch hinzu, dass große zusammenhängende Speicherbereiche schwieriger zu finden sind, als kleine Blöcke. Je nach Fragmentierung des Heaps kann es dann mal funktionieren und ein anderes Mal nicht.

Zitat:

Zitat von Jim Carrey (Beitrag 1352929)
Das mit dem OutOfMemory... wieso fängst du den nicht ab und wenn er auftritt, brichst du die aktuelle Funktion ab?

Delphi-Quellcode:
EOutOfMemory
abfangen ist okay, aber meiner Meinung nach nicht optimal, da du dies dann bei so wirklich jedem
Delphi-Quellcode:
Create
,
Delphi-Quellcode:
GetMem
,
Delphi-Quellcode:
SetLength
, etc. machen müsstest. Natürlich auch bei allen Funktionen, die intern irgendwie Speicher auf dem Heap reservieren.

Du solltest mal schauen, ob es wirklich notwendig ist ALLE Bitmaps permanent im Speicher zu halten.

Jim Carrey 7. Nov 2016 22:26

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

Du solltest mal schauen, ob es wirklich notwendig ist ALLE Bitmaps permanent im Speicher zu halten.
Finde ich auch ein bisschen komisch... wie viele Instanzen sind das denn, dass du an die 2 GB bzw 3 GB Grenze kommst?

Bei mir persönlich waren Speicherprobleme ausnahmslos immer auf schlechten Code zurückzuführen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:38 Uhr.
Seite 1 von 5  1 23     Letzte » 

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