Linux系统下Delphi应用如何获取当前进程的内存和CPU使用率?
Linux平台Delphi获取进程内存与CPU占用方案
Linux平台下无需引入额外第三方依赖,直接读取系统原生的/proc虚拟文件系统即可实现需求,这是Linux用户态程序获取进程运行指标的通用实现方式,适配所有主流Linux发行版,同时兼容Delphi 10.2及以上支持Linux 64位编译的所有Delphi版本。
获取当前进程内存占用
直接读取/proc/self/status文件,筛选VmRSS(物理内存占用,单位KB)、VmSize(虚拟内存占用,单位KB)字段即可,示例代码如下:
function GetProcessMemoryUsage(out PhysMemKB, VirtMemKB: UInt64): Boolean; var SL: TStringList; I: Integer; Line: string; begin Result := False; PhysMemKB := 0; VirtMemKB := 0; if not FileExists('/proc/self/status') then Exit; SL := TStringList.Create; try SL.LoadFromFile('/proc/self/status'); for I := 0 to SL.Count - 1 do begin Line := Trim(SL[I]); if Pos('VmRSS:', Line) = 1 then PhysMemKB := StrToUInt64(Trim(Copy(Line, 7, Pos('kB', Line) -7))) else if Pos('VmSize:', Line) = 1 then VirtMemKB := StrToUInt64(Trim(Copy(Line, 7, Pos('kB', Line) -7))); end; Result := (PhysMemKB > 0) or (VirtMemKB > 0); finally SL.Free; end; end;
获取当前进程CPU使用率
Linux没有直接返回进程CPU使用率的内核接口,需要通过两次采样的差值计算得到:
- 第一次采样:读取进程总CPU时间(
/proc/self/stat文件的第14、15项之和,单位为系统时钟节拍)、系统总CPU时间(/proc/stat第一行所有数值之和) - 间隔指定时间(通常取100ms~1000ms)后第二次采样相同指标
- CPU使用率 = (进程CPU时间差值 / 系统总CPU时间差值) * 100%
示例代码如下:
uses Posix.Unistd; var LastProcTime: UInt64 = 0; LastSysTime: UInt64 = 0; CLK_TCK: Integer = 0; function GetTickCountPerSecond: Integer; begin if CLK_TCK = 0 then CLK_TCK := sysconf(_SC_CLK_TCK); Result := CLK_TCK; end; function GetProcessCpuTime: UInt64; var SL: TStringList; Fields: TArray<string>; begin Result := 0; if not FileExists('/proc/self/stat') then Exit; SL := TStringList.Create; try SL.LoadFromFile('/proc/self/stat'); Fields := SL[0].Split([' ']); if Length(Fields) >= 15 then // 第14项utime,15项stime,单位为时钟节拍 Result := StrToUInt64(Fields[13]) + StrToUInt64(Fields[14]); finally SL.Free; end; end; function GetSystemTotalCpuTime: UInt64; var SL: TStringList; Fields: TArray<string>; I: Integer; begin Result := 0; if not FileExists('/proc/stat') then Exit; SL := TStringList.Create; try SL.LoadFromFile('/proc/stat'); Fields := SL[0].Split([' '], TStringSplitOptions.ExcludeEmpty); for I := 1 to Length(Fields) -1 do Result := Result + StrToUInt64(Fields[I]); finally SL.Free; end; end; function GetProcessCpuUsage: Double; var CurrProcTime, CurrSysTime: UInt64; DeltaProc, DeltaSys: UInt64; begin Result := 0; CurrProcTime := GetProcessCpuTime; CurrSysTime := GetSystemTotalCpuTime; if (LastProcTime = 0) or (LastSysTime = 0) then begin LastProcTime := CurrProcTime; LastSysTime := CurrSysTime; Exit; end; DeltaProc := CurrProcTime - LastProcTime; DeltaSys := CurrSysTime - LastSysTime; if DeltaSys > 0 then // 此处返回总CPU占比,多核场景下最大值可超过100%,符合Linux系统统计逻辑 Result := (DeltaProc / DeltaSys) * 100; LastProcTime := CurrProcTime; LastSysTime := CurrSysTime; end;
注意事项
- 若需要更高性能的读取逻辑,可直接用
TFileStream读取文件内容代替TStringList,减少内存分配开销 proc文件系统是内核虚拟出来的文件,读取操作不会产生实际磁盘IO,性能开销极低
内容的提问来源于stack exchange,提问作者Sds Lee
相关产品推荐
相关产品推荐

