Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
Delphi 12 Athens
|
AW: Speicherbenutzung nach wochenlanger Benutzung
12. Jun 2012, 12:48
GlobalMemoryStatusEx (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.
GetMemoryManagerState
früher gab es noch AllocMemCount, AllocMemSize und GetHeapStatus
[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)
$2B or not $2B
Geändert von himitsu (12. Jun 2012 um 13:00 Uhr)
|