Často píšu programy které běží dlouho a tak mne zajímá, zda se tam neděje něco co nechci. V takovém případě si do logu zapisuji stav programu (tedy kromě jiného samozřejmě). Sice existují knihovny, ale pro mé potřeby většinou stačí jednoduchá funkce.
Následující funkce vrátí stav resources a dostupné paměti
function GetResourceStatus: string;
var
iGdi, iUser: Integer;
dwHandleCount: Cardinal;
m: TMemoryStatusEx;
begin
iGdi := GetGuiResources(GetCurrentProcess, GR_GDIOBJECTS);
iUser := GetGuiResources(GetCurrentProcess, GR_USEROBJECTS);
GetProcessHandleCount(GetCurrentProcess, dwHandleCount);
FillChar(m, SizeOf(m), 0);
m.dwLength := SizeOf( m );
GlobalMemoryStatusEx(m);
Result := Format('Handles: gdi: %d, user: %d, handle: %d, mem: %d', [iGdi, iUser, dwHandleCount, m.ullAvailVirtual]);
end;
Na test stačí aplikace s tlačítkem a obsluhou OnClick
procedure TForm12.Button1Click(Sender: TObject);
var
oFile: TFileStream;
sFile: string;
oBmp: TBitmap;
oChk: TCheckBox;
p: Pointer;
procedure CheckFile;
begin
if not FileExists(sFile) then
TFile.WriteAllText(sFile, 'nothing'); // from System.IOUtils;
end;
begin
sFile := ChangeFileExt(ParamStr(0),'.txt');
CheckFile; // file for leak
Memo1.Lines.Add(GetResourceStatus);
oFile := TFileStream.Create(sFile, fmOpenRead or fmShareDenyNone) ; // leak handle
oBmp := TBitmap.Create(100, 100); // leak gdi
oChk:= TCheckBox.Create(nil); // leak user
oChk.Parent := Self;
oChk.SetBounds(100, 0, 12, 12);
GetMem(p, 1024*1024); // leak memory
end;
Samozřejmě, pokud máte spuštěnou aplikaci tak můžete zobrazit podobný stav třeba přes správce úloh (jak je na obrázku nahoře), nebo použít specializované programy, které pro některé typy handle dají více informací (jako např. Task Manager DeLuxe nebo System Informer).