全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:3724
推到 Plurk!
推到 Facebook!

获取内存及CPU信息的函数

 
Vicen
高階會員


發表:13
回覆:145
積分:151
註冊:2005-03-14

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-05-04 13:16:14 IP:221.226.xxx.xxx 未訂閱
经常来 class="code"> > 当前系统的物理内存总量 > 虚拟内存总量 > 页面内存总量 > 当前物理内存可用容量 > 当前虚拟内存可用容量 > 当前页面内存可用容量 > 当前内存的使用率 > 系统中CPU的个数 > 当前CPU的使用率 > CPU的生产厂家 先看看使用的方法吧,非常简单。
Uses MemoryCpuUtils;//首先引用该单元    //声明下列变量用来存储读取的数值
Var
  iTotalPhysics, iTotalVirtual, iTotalPageFile, 
  iCurPhysics, iCurVirtual, iCurPageFile : DWord;    //CPU数量
Format('系统中共有 %d 个CPU中央存储器',[GetCPUCount]);
//其中i表示获取第几个CPU的使用率
Format('CPU使用率为 #%d - %5.2f%%',[i,GetCPUUsage(i)*100]);
//初始化OR读取各内存总量
GetMemoryTotalSize(iTotalPhysics ,iTotalVirtual ,iTotalPageFile);
//物理内存总量
InttoStr(Round(iTotalPhysics/1024/1024))   ' MB';
//虚拟内存总量
InttoStr(Round(iTotalVirtual/1024/1024))   ' MB';
//页面内存(交换内存)总量
InttoStr(Round(iTotalPageFile/1024/1024))   ' MB';
//读取各内存当前可用容量
GetMemoryTotalSize(iCurPhysics,iCurVirtual,iCurPageFile);
//物理内存可用容量
InttoStr(Round(iCurPhysics/1024/1024))   ' MB';
//虚拟内存可用容量
InttoStr(Round(iCurVirtual/1024/1024))   ' MB';
//页面内存(交换内存)可用容量
InttoStr(Round(iCurPageFile/1024/1024))   ' MB';
//获取内存使用率
Format('当前内存使用率为 %5.2f%%',[GetMemoryUsage]);
//直接获取CPU厂商
GetCPUVendor    那么如何计算当前各内存使用比例呢?
//物理内存使用比
Format('物理内存使用比为 %5.2f%%',[iCurPhysics/iTotalPhysics*100]);
//虚拟内存使用比
Format('虚拟内存使用比为 %5.2f%%',[iCurVirtual/iTotalVirtual*100]);
//页面内存使用比
Format('页面内存使用比为 %5.2f%%',[iCurPageFile/iTotalPageFile*100]);
下载后直接引用即可,如果您还不是会员,可以直接COPY下面的代码。
{==================================================================}
{ Get Memory And Cpu Informations Utils                            }
{==================================================================}    Unit MemoryCpuUtils;    interface    Uses
  Windows, SysUtils;    type
  TVendor = array[0..11] of Char;    {内存区}
//获取物理内存、虚拟内存、交换区(页面)内存的总容量,做初始化动作。
procedure GetMemoryTotalSize(Var iPhysicsMemoryTotalSize,
                                 iVirtualMemoryTotalSize,
                                 iPageFileMemoryTotalSize : DWORD);    //获取当前物理内存、虚拟内存、交换区(页面)内存的实时可用容量,做监控显示动作。
procedure GetMemoryCurrentSize(Var iPhysicsMemoryCurrentSize,
                                   iVirtualMemoryCurrentSize,
                                   iPageFileMemoryCurrentSize : DWORD);    //返回内存当前使用率 总的是100%,传回的是0-100%间的使用率,可以自己做转换。                              
function GetMemoryUsage : Double;    {CPU区}
//刷新CPU数据
procedure CollectCPUData;    //获取CPU在系统中的总数
function GetCPUCount: Integer;    //获取CPU使用率
function GetCPUUsage(Index: Integer): Double;    procedure ReleaseCPUData;    //获取CPU制造厂商
function GetCPUVendor : TVendor; assembler; register;    implementation    {$ifndef ver110}      {$ifndef ver90}
  {$ifndef ver100}
  {$define UseInt64}
  {$endif}
  {$endif}      {$ifdef UseInt64}
  type TInt64 = Int64;
  {$else}
  type TInt64 = Comp;
  {$endif}    {$else}      type TInt64 = TLargeInteger;    {$endif}    type
  PInt64 = ^TInt64;    type
  TPERF_DATA_BLOCK = record
    Signature : array[0..4 - 1] of WCHAR;
    LittleEndian : DWORD;
    Version : DWORD;
    Revision : DWORD;
    TotalByteLength : DWORD;
    HeaderLength : DWORD;
    NumObjectTypes : DWORD;
    DefaultObject : Longint;
    SystemTime : TSystemTime;
    Reserved: DWORD;
    PerfTime : TInt64;
    PerfFreq : TInt64;
    PerfTime100nSec : TInt64;
    SystemNameLength : DWORD;
    SystemNameOffset : DWORD;
  end;      PPERF_DATA_BLOCK = ^TPERF_DATA_BLOCK;      TPERF_OBJECT_TYPE = record
    TotalByteLength : DWORD;
    DefinitionLength : DWORD;
    HeaderLength : DWORD;
    ObjectNameTitleIndex : DWORD;
    ObjectNameTitle : LPWSTR;
    ObjectHelpTitleIndex : DWORD;
    ObjectHelpTitle : LPWSTR;
    DetailLevel : DWORD;
    NumCounters : DWORD;
    DefaultCounter : Longint;
    NumInstances : Longint;
    CodePage : DWORD;
    PerfTime : TInt64;
    PerfFreq : TInt64;
  end;      PPERF_OBJECT_TYPE = ^TPERF_OBJECT_TYPE;      type
    TPERF_COUNTER_DEFINITION = record
      ByteLength : DWORD;
      CounterNameTitleIndex : DWORD;
      CounterNameTitle : LPWSTR;
      CounterHelpTitleIndex : DWORD;
      CounterHelpTitle : LPWSTR;
      DefaultScale : Longint;
      DetailLevel : DWORD;
      CounterType : DWORD;
      CounterSize : DWORD;
      CounterOffset : DWORD;
    end;        PPERF_COUNTER_DEFINITION = ^TPERF_COUNTER_DEFINITION;        TPERF_COUNTER_BLOCK = record
      ByteLength : DWORD;
    end;        PPERF_COUNTER_BLOCK = ^TPERF_COUNTER_BLOCK;        TPERF_INSTANCE_DEFINITION = record
      ByteLength : DWORD;
      ParentObjectTitleIndex : DWORD;
      ParentObjectInstance : DWORD;
      UniqueID : Longint;
      NameOffset : DWORD;
      NameLength : DWORD;
    end;        PPERF_INSTANCE_DEFINITION = ^TPERF_INSTANCE_DEFINITION;      {$ifdef ver130}
  {$L-}         // The L  causes internal error in Delphi 5 compiler
  {$O-}         // The O  causes internal error in Delphi 5 compiler
  {$Y-}         // The Y  causes internal error in Delphi 5 compiler
  {$endif}    {$ifndef ver110}
  type
    TInt64F = TInt64;
  {$else}
  type
    TInt64F = Extended;
{$endif}    {$ifdef ver110}
function FInt64(Value: TInt64): TInt64F;
function Int64D(Value: DWORD): TInt64;
{$else}
type
  FInt64 = TInt64F;
  Int64D = TInt64;
{$endif}    {$ifdef ver110}
function FInt64(Value: TInt64): TInt64F;
Var
  V: TInt64;
begin
  if (Value.HighPart and $80000000) = 0 then // positive value
  begin
    result:=Value.HighPart;
    result:=result*$10000*$10000;
    result:=result Value.LowPart;
  end
  else
  begin
    V.HighPart:=Value.HighPart xor $FFFFFFFF;
    V.LowPart:=Value.LowPart xor $FFFFFFFF;
    result:= -1 - FInt64(V);
  end;
end;    function Int64D(Value: DWORD): TInt64;
begin
  Result.LowPart:=Value;
  Result.HighPart := 0; // positive only
end;
{$endif}    Const
  Processor_IDX_Str = '238';
  Processor_IDX = 238;
  CPUUsageIDX = 6;    type
  AInt64F = array[0..$FFFF] of TInt64F;
  PAInt64F = ^AInt64F;    Var
  _PerfData : PPERF_DATA_BLOCK;
  _BufferSize: Integer;
  _POT : PPERF_OBJECT_TYPE;
  _PCD: PPerf_Counter_Definition;
  _ProcessorsCount: Integer;
  _Counters: PAInt64F;
  _PrevCounters: PAInt64F;
  _SysTime: TInt64F;
  _PrevSysTime: TInt64F;
  _IsWinNT: Boolean;      _W9xCollecting: Boolean;
  _W9xCpuUsage: DWORD;
  _W9xCpuKey: HKEY;    procedure GetMemoryTotalSize(Var iPhysicsMemoryTotalSize,
                             iVirtualMemoryTotalSize,
                             iPageFileMemoryTotalSize : DWORD);
{
iPhysicsMemoryTotalSize 物理内存总容量
iVirtualMemoryTotalSize 虚拟内存总容量
iPageFileMemoryTotalSize 交换内存(页面)总容量
}
Var
  msMemory : TMemoryStatus;
begin
  msMemory.dwLength := SizeOf(msMemory);
  GlobalMemoryStatus(msMemory);
  iPhysicsMemoryTotalSize := msMemory.dwTotalPhys;
  iVirtualMemoryTotalSize := msMemory.dwTotalVirtual;
  iPageFileMemoryTotalSize := msMemory.dwTotalPageFile;
end;    procedure GetMemoryCurrentSize(Var iPhysicsMemoryCurrentSize,
                              iVirtualMemoryCurrentSize,
                              iPageFileMemoryCurrentSize : DWORD);
{
iPhysicsMemoryCurrentSize 物理内存可用容量
iVirtualMemoryCurrentSize 虚拟内存可用容量
iPageFileMemoryCurrentSize 交换内存(页面)可用容量
}
Var
  msMemory : TMemoryStatus;
begin
  msMemory.dwLength := SizeOf(msMemory);
  GlobalMemoryStatus(msMemory);
  iPhysicsMemoryCurrentSize := msMemory.dwAvailPhys;
  iVirtualMemoryCurrentSize := msMemory.dwAvailVirtual;
  iPageFileMemoryCurrentSize := msMemory.dwAvailPageFile;
end;    function GetMemoryUsage : Double;
{
返回内存当前使用率 总的是100%,传回的是0-100%间的使用率,可以自己做转换。
}
Var
  msMemory : TMemoryStatus;
begin
  try
    msMemory.dwLength := SizeOf(msMemory);
    GlobalMemoryStatus(msMemory);
    Result := msMemory.dwMemoryLoad;
  except
    Result := 0;
  end;
end;    function GetCPUCount: Integer;
{
获取CPU数量
}
begin
  if _IsWinNT then
  begin
    if _ProcessorsCount < 0 then
      CollectCPUData;
    Result:=_ProcessorsCount;
  end
  else
  begin
    Result:=1;
  end;
end;    procedure ReleaseCPUData;
Var
  H: HKEY;
  R: DWORD;
  DwDataSize, DwType: DWORD;
begin
  if _IsWinNT then Exit;
  if Not _W9xCollecting then Exit;
  _W9xCollecting := False;
  RegCloseKey(_W9xCpuKey);
  R := RegOpenKeyEx( HKEY_DYN_DATA, 'PerfStats\StopStat', 0, KEY_ALL_ACCESS, H);
  if R <> ERROR_SUCCESS then Exit;
  dwDataSize := Sizeof(DWORD);
  RegQueryValueEx(H,'KERNEL\CPUUsage', Nil, @DwType, PBYTE(@_W9xCpuUsage), @DwDataSize);
  RegCloseKey(H);
end;    function GetCPUUsage(Index: Integer): Double;
{
获取CPU当前使用率
}
begin
  if _IsWinNT then
  begin
    if _ProcessorsCount < 0 then CollectCPUData;
    if (Index >= _ProcessorsCount) Or (Index < 0) then
      Raise Exception.Create('CPU index out of bounds');
    if _PrevSysTime = _SysTime then
      Result := 0
    else
      Result := 1-(_Counters[index] - _PrevCounters[index])/(_SysTime-_PrevSysTime);
  end
  else
  begin
    if Index <> 0 then
      Raise Exception.Create('CPU index out of bounds');
    if Not _W9xCollecting then
      CollectCPUData;
    Result := _W9xCpuUsage/100;
  end;
end;    Var
  VI: TOSVERSIONINFO;    procedure CollectCPUData;
Var
  BS, i : Integer;
  _PCB_Instance : PPERF_COUNTER_BLOCK;
  _PID_Instance : PPERF_INSTANCE_DEFINITION;
  ST : TFileTime;
  H : HKEY;
  R : DWORD;
  DwDataSize, dwType: DWORD;
begin
  if _IsWinNT then
  begin
    BS:=_BufferSize;
    while RegQueryValueEx( HKEY_PERFORMANCE_DATA, Processor_IDX_Str, nil, nil,
            PByte(_PerfData), @BS ) = ERROR_MORE_DATA do
    begin
      INC(_BufferSize,$1000);
      BS:=_BufferSize;
      ReallocMem( _PerfData, _BufferSize );
    end;        _POT := PPERF_OBJECT_TYPE(DWORD(_PerfData)   _PerfData.HeaderLength);
    for i := 1 to _PerfData.NumObjectTypes do
    begin
      if _POT.ObjectNameTitleIndex = Processor_IDX then Break;
      _POT := PPERF_OBJECT_TYPE(DWORD(_POT)   _POT.TotalByteLength);
    end;        if _POT.ObjectNameTitleIndex <> Processor_IDX then
      Raise Exception.Create('Unable to locate the "Processor" performance object');        if _ProcessorsCount < 0 then
    begin
      _ProcessorsCount:=_POT.NumInstances;
      GetMem(_Counters,_ProcessorsCount*SizeOf(TInt64));
      GetMem(_PrevCounters,_ProcessorsCount*SizeOf(TInt64));
    end;        _PCD := PPERF_Counter_DEFINITION(DWORD(_POT)   _POT.HeaderLength);
    for i := 1 to _POT.NumCounters do
    begin
      if _PCD.CounterNameTitleIndex = CPUUsageIDX then Break;
      _PCD := PPERF_COUNTER_DEFINITION(DWORD(_PCD)   _PCD.ByteLength);
    end;        if _PCD.CounterNameTitleIndex <> CPUUsageIDX then
      Raise Exception.Create('Unable to locate the "% of CPU usage" performance counter');        _PID_Instance := PPERF_INSTANCE_DEFINITION(DWORD(_POT)   _POT.DefinitionLength);
    for i := 0 to _ProcessorsCount-1 do
    begin
      _PCB_Instance := PPERF_COUNTER_BLOCK(DWORD(_PID_Instance)   _PID_Instance.ByteLength);
      _PrevCounters[i]:=_Counters[i];
      _Counters[i]:=FInt64(PInt64(DWORD(_PCB_Instance)   _PCD.CounterOffset)^);
      _PID_Instance := PPERF_INSTANCE_DEFINITION(DWORD(_PCB_Instance)   _PCB_Instance.ByteLength);
    end;        _PrevSysTime:=_SysTime;
    SystemTimeToFileTime(_PerfData.SystemTime, ST);
    _SysTime:=FInt64(TInt64(ST));
  end
  else
  begin
    if Not _W9xCollecting then
    begin
      R:=RegOpenKeyEx( HKEY_DYN_DATA, 'PerfStats\StartStat', 0, KEY_ALL_ACCESS, H );
      if R <> ERROR_SUCCESS then
        Raise Exception.Create('Unable to start performance monitoring');
      dwDataSize:=sizeof(DWORD);
      RegQueryValueEx( H, 'KERNEL\CPUUsage', nil, @dwType, PBYTE(@_W9xCpuUsage), @dwDataSize );
      RegCloseKey(H);
      R:=RegOpenKeyEx( HKEY_DYN_DATA, 'PerfStats\StatData', 0,KEY_READ, _W9xCpuKey );
      if R <> ERROR_SUCCESS then
        Raise Exception.Create('Unable to read performance data');
      _W9xCollecting:=True;
    end;        dwDataSize:=sizeof(DWORD);
    RegQueryValueEx( _W9xCpuKey, 'KERNEL\CPUUsage', nil,@dwType, PBYTE(@_W9xCpuUsage), @dwDataSize );
  end;
end;    function GetCPUVendor : TVendor; assembler; register;
asm
  PUSH    EBX                                        {Save affected register}
  PUSH    EDI
  MOV     EDI,EAX                        {@Result (TVendor)}
  MOV     EAX,0
  DW      $A20F                                {CPUID Command}
  MOV     EAX,EBX
  XCHG                EBX,ECX     {save ECX result}
  MOV                        ECX,4
@1:
  STOSB
  SHR     EAX,8
  LOOP    @1
  MOV     EAX,EDX
  MOV                        ECX,4
@2:
  STOSB
  SHR     EAX,8
  LOOP    @2
  MOV     EAX,EBX
  MOV                        ECX,4
@3:
  STOSB
  SHR     EAX,8
  LOOP    @3
  POP     EDI                                        {Restore registers}
  POP     EBX
end;    initialization
  _ProcessorsCount:= -1;
  _BufferSize:= $2000;
  _PerfData := AllocMem(_BufferSize);
  VI.dwOSVersionInfoSize := SizeOf(VI);
  if Not GetVersionEx(VI) then
    Raise Exception.Create('Can''t get the Windows version');
  _IsWinNT := VI.dwPlatformId = VER_PLATFORM_WIN32_NT;    finalization
  ReleaseCPUData;
  FreeMem(_PerfData);
  
end.    
發表人 - vicen 於 2005/05/04 17:22:44
附加檔案:70304_MemoryCpuUtils.pas
jimmychn
一般會員


發表:3
回覆:21
積分:19
註冊:2002-09-09

發送簡訊給我
#2 引用回覆 回覆 發表時間:2012-05-08 16:09:10 IP:61.30.xxx.xxx 訂閱
感謝分享!
趕緊試試看!
------
>>>好心有好報
系統時間:2024-11-21 19:53:26
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!