AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Speicherbenutzung nach wochenlanger Benutzung

Speicherbenutzung nach wochenlanger Benutzung

Ein Thema von Alex_ITA01 · begonnen am 12. Jun 2012 · letzter Beitrag vom 20. Jun 2012
Antwort Antwort
Alex_ITA01

Registriert seit: 22. Sep 2003
1.134 Beiträge
 
Delphi 12 Athens
 
#1

AW: Speicherbenutzung nach wochenlanger Benutzung

  Alt 12. Jun 2012, 11:20
Ok, was wäre denn der richtige Wert für den Speicherbedarf?
Das Erscheinungsbild ist, dass wenn dieser Wert (WorkingSetSize) bei 1,55GB ist, dass dann in der Anwendung alles möglich in die "Hose" geht. Ich denke wegen der 2GB Grenze pro Anwendung...
Ich gucke mir FastMM an, hoffe ich kann irgendwie was feststellen.

Gruß
Let's fetz sprach der Frosch und sprang in den Mixer
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.374 Beiträge
 
Delphi 12 Athens
 
#2

AW: Speicherbenutzung nach wochenlanger Benutzung

  Alt 12. Jun 2012, 11:48
MSDN-Library durchsuchenGlobalMemoryStatusEx (ullAvailVirtual) oder du rechnest ein bissl mit den Werten rum, welche die FastMM (der DelphiMM) liefert.

ReportMemoryLeaksOnShutdown := True; wenn fast FastMM schon im Delphi integriert ist.

Delphi-Referenz durchsuchenGetMemoryManagerState
früher gab es noch Delphi-Referenz durchsuchenAllocMemCount, Delphi-Referenz durchsuchenAllocMemSize und Delphi-Referenz durchsuchenGetHeapStatus



[add]
Das Ding hatte ich vor Langem mal zusammengehackt. (wegen der Recordfunktionen sollte es wohl ab D2006/TDE laufen)
- mit .Init initialisieren
- z.B. alle 10 Sekunden .Update aufrufen
- und alle 5 Minuten .Execute (den Result-String in eine Logdatei)
Delphi-Quellcode:
type
  TProcessInfoX = record
    IntStart, IntCount: Cardinal; // GetTickCount
    // Process
    HandlesSum, HandlesMin, HandlesMax: Cardinal; // GetProcessHandleCount
    KernelTimeStart,
    KernelTimeLast, KernelTimeMin, KernelTimeMax: Int64{TFileTime}; // GetProcessTimes(lpKernelTime)
    UserTimeStart,
    UserTimeLast, UserTimeMin, UserTimeMax: Int64{TFileTime}; // GetProcessTimes(lpUserTime)
    MemorySum, MemoryMin, MemoryMax: UInt64; // GlobalMemoryStatusEx(ullAvailVirtual)
    // Global
    MemoryLoadSum, MemoryLoadMin, MemoryLoadMax: Cardinal; // GlobalMemoryStatusEx(dwMemoryLoad)
    FreeRAMSum, FreeRAMMin, FreeRAMMax: UInt64; // GlobalMemoryStatusEx(ullAvailPhys)
    PageFileSum, PageFileMin, PageFileMax: UInt64; // GlobalMemoryStatusEx(ullAvailPageFile)
    //
    procedure Init; // bei Programmstart initialisieren
    procedure Update; // zwischendurch updaten, für die Min/Max-Berechnung
    function Execute: String; // am Ende eines Messintervalls alles Berechnen und neues Intervall beginnen
  end;

{ TProcessInfoX }

procedure TProcessInfoX.Init;
begin
  FillChar(Self, SizeOf(Self), 0);
  IntStart := GetTickCount;
  IntCount := 1;
  Execute;
end;

procedure TProcessInfoX.Update;
var
  H: THandle;
  Handles: Cardinal;
  KernelTime, UserTime, X: Int64{TFileTime};
  _Time: TFileTime;
  MemoryStatus: TMemoryStatusEx;
begin
  Inc(IntCount);
  H := GetCurrentProcess;
  if GetProcessHandleCount(H, Handles) then begin
    Inc(HandlesSum, Handles);
    if HandlesMin > Handles then HandlesMin := Handles;
    if HandlesMax < Handles then HandlesMax := Handles;
  end;
  if GetProcessTimes(H, _Time, _Time, TFileTime(KernelTime), TFileTime(UserTime)) then begin
    X := KernelTime - KernelTimeLast;
    KernelTimeLast := KernelTime;
    if KernelTimeMin > X then KernelTimeMin := X;
    if KernelTimeMax < X then KernelTimeMax := X;
    X := UserTime - UserTimeLast;
    UserTimeLast := UserTime;
    if UserTimeMin > X then UserTimeMin := X;
    if UserTimeMax < X then UserTimeMax := X;
  end;
  MemoryStatus.dwLength := SizeOf(MemoryStatus);
  if GlobalMemoryStatusEx(MemoryStatus) then
    with MemoryStatus do begin
      X := ullTotalVirtual - ullAvailVirtual;
      Inc(MemorySum, X);
      if MemoryMin > X then MemoryMin := X;
      if MemoryMax < X then MemoryMax := X;
      Inc(MemoryLoadSum, dwMemoryLoad);
      if MemoryLoadMin > dwMemoryLoad then MemoryLoadMin := dwMemoryLoad;
      if MemoryLoadMax < dwMemoryLoad then MemoryLoadMax := dwMemoryLoad;
      X := ullAvailPhys;
      Inc(FreeRAMSum, X);
      if FreeRAMMin > X then FreeRAMMin := X;
      if FreeRAMMax < X then FreeRAMMax := X;
      X := ullTotalPageFile - ullAvailPageFile;
      Inc(PageFileSum, X);
      if PageFileMin > X then PageFileMin := X;
      if PageFileMax < X then PageFileMax := X;
    end;
end;

function TProcessInfoX.Execute: String;
function RD(i: UInt64): Integer; inline;
  begin
    Result := (i + 787200) shr 20;
  end;
var
  H: THandle;
  _Time: TFileTime;
  KernelTime, UserTime: Int64{TFileTime};
  KernelTimeMean, UserTimeMean: Int64{TFileTime};
  Handles, HandlesMean, MemoryLoadMean: Cardinal;
  ProcessLoad, ProcessUserT, IntTime: Cardinal;
  MemoryMean, FreeRAMMean, PageFileMean: UInt64;
  MemoryStatus: TMemoryStatusEx;
  New: TProcessInfoX;
  MMS: TMemoryManagerState;
  UsedDelphiMM, ReservedDelphiMM: Cardinal;
  i: Integer;
begin
  if (GetTickCount - IntStart) > 100 then
    Update;
  IntTime := GetTickCount - IntStart;
  if IntTime <= 0 then
    IntTime := 1; // kein DivByZZero
  H := GetCurrentProcess;

  FillChar(New, SizeOf(Self), 0);
  New.IntStart := GetTickCount;
  New.IntCount := 1;

  if GetProcessHandleCount(H, Handles) then begin
    HandlesMean := HandlesSum div IntCount;
    New.HandlesSum := Handles;
    New.HandlesMin := Handles;
    New.HandlesMax := Handles;
  end else
    HandlesMean := 0;

  if GetProcessTimes(H, _Time, _Time, TFileTime(KernelTime), TFileTime(UserTime)) then begin
    KernelTimeMean := KernelTime - KernelTimeStart;
    UserTimeMean := UserTime - UserTimeStart;
    ProcessLoad := ((UserTimeMean + KernelTimeMean) div 100) div IntTime;
    ProcessUserT := ( UserTimeMean div 100) div IntTime;
    New.KernelTimeStart := KernelTime;
    New.UserTimeStart := UserTime;
    New.KernelTimeLast := KernelTime;
    New.UserTimeLast := UserTime;
    New.KernelTimeMin := High(Int64);
    New.UserTimeMin := High(Int64);
    New.KernelTimeMax := 0;
    New.UserTimeMax := 0;
  end else begin
    ProcessLoad := 0;
    ProcessUserT := 0;
  end;

  MemoryStatus.dwLength := SizeOf(MemoryStatus);
  if GlobalMemoryStatusEx(MemoryStatus) then begin
    with MemoryStatus do begin
      MemoryMean := MemorySum div IntCount;
      MemoryLoadMean := MemoryLoadSum div IntCount;
      FreeRAMMean := FreeRAMSum div IntCount;
      PageFileMean := PageFileSum div IntCount;
      New.MemorySum := ullTotalVirtual - ullAvailVirtual;
      New.MemoryLoadSum := dwMemoryLoad;
      New.FreeRAMSum := ullAvailPhys;
      New.PageFileSum := ullTotalPageFile - ullAvailPageFile;
      New.MemoryMin := New.MemorySum;
      New.MemoryLoadMin := New.MemoryLoadSum;
      New.FreeRAMMin := New.FreeRAMSum;
      New.PageFileMin := New.PageFileSum;
      New.MemoryMax := New.MemorySum;
      New.MemoryLoadMax := New.MemoryLoadSum;
      New.FreeRAMMax := New.FreeRAMSum;
      New.PageFileMax := New.PageFileSum;
    end;
  end else begin
    MemoryMean := 0;
    MemoryLoadMean := 0;
    FreeRAMMean := 0;
    PageFileMean := 0;
  end;


  GetMemoryManagerState(MMS);
  UsedDelphiMM := MMS.TotalAllocatedMediumBlockSize + MMS.TotalAllocatedLargeBlockSize;
  For i := 0 to NumSmallBlockTypes - 1 do
    Inc(UsedDelphiMM, MMS.SmallBlockTypeStates[i].InternalBlockSize * MMS.SmallBlockTypeStates[i].AllocatedBlockCount);
  ReservedDelphiMM := MMS.ReservedMediumBlockAddressSpace + MMS.ReservedLargeBlockAddressSpace;

  Result := Format('CPU: %2d %% (%2d) Memory: %4d MB (%4d-%4d) MemoryLoad: %2d %% (%2d-%2d) DelphiMM: %4d MB (res %3d MB) '
    + 'FreeRAM: %4d MB (%4d-%4d) PageFile: %4d MB (%4d-%4d) Handles: %3d (%3d-%3d)', [
    ProcessLoad, ProcessUserT,
    RD(MemoryMean), RD(MemoryMin), RD(MemoryMax),
    MemoryLoadMean, MemoryLoadMin, MemoryLoadMax,
    RD(UsedDelphiMM), RD(ReservedDelphiMM),
    RD(FreeRAMMean), RD(FreeRAMMin), RD(FreeRAMMax),
    RD(PageFileMean), RD(PageFileMin), RD(PageFileMax),
    HandlesMean, HandlesMin, HandlesMax]);

  Self := New;
end;
(als Zitat sieht der Code hübscher aus)
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (12. Jun 2012 um 12:00 Uhr)
  Mit Zitat antworten Zitat
Alex_ITA01

Registriert seit: 22. Sep 2003
1.134 Beiträge
 
Delphi 12 Athens
 
#3

AW: Speicherbenutzung nach wochenlanger Benutzung

  Alt 20. Jun 2012, 12:23
Hallo himitsu,
gibts die Funktion "GetProcessHandleCount" unter Delphi 2009 (Win7) nicht (mehr)?

Wenn nein, welche könnte ich als Alternative nutzen?

Gruß
Let's fetz sprach der Frosch und sprang in den Mixer
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#4

AW: Speicherbenutzung nach wochenlanger Benutzung

  Alt 20. Jun 2012, 12:49
Siehe MSDN: GetProcessHandleCount

Übersetzung (scheint zu funktionieren):
Delphi-Quellcode:
uses windows;
//...
function GetProcessHandleCount(hProcess: THandle; var pdwHandleCount: DWORD): BOOL; stdcall; external 'kernel32.dll';
Intellekt ist das Verstehen von Wissen. Verstehen ist der wahre Pfad zu Einsicht. Einsicht ist der Schlüssel zu allem.

Geändert von BUG (20. Jun 2012 um 13:03 Uhr) Grund: WORD -> DWORD, nichtmehr ganz ungetestet
  Mit Zitat antworten Zitat
sahimba

Registriert seit: 14. Nov 2011
Ort: Berlin, Hauptstadt der DDR
137 Beiträge
 
Delphi 10 Seattle Professional
 
#5

AW: Speicherbenutzung nach wochenlanger Benutzung

  Alt 20. Jun 2012, 12:55
ReportMemoryLeaksOnShutDown hat ein Defizit: es zeigt Dir tatsächlich nur Leaks an. Handelt es sich jedoch um steigenden Speicherbedarf welcher bei Programmende sauber abgeräumt wird, so hilft dir das Ganze kein Stück weiter. Genau dafür habe ich ein Tool gebaut (Infos finden sich unter http://ddobjects.de/ddserver). Die auf der Seite bereitstehende Version ist veraltet, habe mich lange nicht drum gekümmert, ich bin aber just dabei diese zu aktuelisieren (XE2 32bit wird bereits unterstützt, einige neue Features sind hinzugekommen etc.).
Wenn Du magst, melde Dich per PM und ich kann Dir kurzfristig was zur Verfügung stellen.
  Mit Zitat antworten Zitat
Alex_ITA01

Registriert seit: 22. Sep 2003
1.134 Beiträge
 
Delphi 12 Athens
 
#6

AW: Speicherbenutzung nach wochenlanger Benutzung

  Alt 20. Jun 2012, 12:59
Hallo BUG,
MSDN habe ich gelesen nur leider gibt es in meiner Windows.pas die Funktion "GetProcessHandleCount" nicht. Unit ist eingebunden aber immernoch "undeklarierter Bezeichner".

Hallo sahimba,
da hast du Recht mit dem ReportMemoryLeaks.
Ich werde erstmal versuchen die Sache oben zum Laufen zu bekommen und melde mich bei Gelegenheit nochmal bei dir. Danke

Grüße
Let's fetz sprach der Frosch und sprang in den Mixer
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#7

AW: Speicherbenutzung nach wochenlanger Benutzung

  Alt 20. Jun 2012, 13:02
MSDN habe ich gelesen nur leider gibt es in meiner Windows.pas die Funktion "GetProcessHandleCount" nicht. Unit ist eingebunden aber immernoch "undeklarierter Bezeichner".
Deshalb habe ich dir ja die Deklaration übersetzt
function GetProcessHandleCount(hProcess: THandle; var pdwHandleCount: DWORD): BOOL; stdcall; external 'kernel32.dll';
Einfach in deinen Code übernehmen.
Intellekt ist das Verstehen von Wissen. Verstehen ist der wahre Pfad zu Einsicht. Einsicht ist der Schlüssel zu allem.
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:02 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz