1

有什么方法可以让服务应用程序只知道它的服务名称就使用了多少内存?

4

3 回答 3

5

首先,您必须使用QueryServiceStatusEx函数或Win32_Service WMI 类将关联进程的 Pid 检索到服务,然后您可以使用GetProcessMemoryInfo函数收集进程的内存使用信息。

检查此示例应用程序

{$APPTYPE CONSOLE}

uses
  ActiveX,
  ComObj,
  Variants,
  Windows,
  psApi,
  SysUtils;

function  GetPidFromService(const ServiceName : string) : DWORD;
const
  WbemUser            ='';
  WbemPassword        ='';
  WbemComputer        ='localhost';
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService   := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
  FWbemObjectSet:= FWMIService.ExecQuery(Format('SELECT ProcessId FROM Win32_Service Where Name="%s"',[ServiceName]),'WQL',wbemFlagForwardOnly);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  if oEnum.Next(1, FWbemObject, iValue) = 0 then
    Result:=FWbemObject.ProcessId;
end;

procedure MemoryInfoService(const ServiceName : string);
var
  hProcess : THandle;
  ppsmemCounters: PPROCESS_MEMORY_COUNTERS;
  cb: DWORD;
begin
  hProcess := OpenProcess(PROCESS_VM_READ or PROCESS_QUERY_INFORMATION, False, GetPidFromService(ServiceName));
  if hProcess <> 0 then
  try
   cb:=SizeOf(PROCESS_MEMORY_COUNTERS);
   GetMem(ppsmemCounters, cb);
   try
   if  GetProcessMemoryInfo( hProcess, ppsmemCounters, cb) then
   begin
      Writeln( Format('PageFaultCount: %d',[ ppsmemCounters.PageFaultCount]));
      Writeln( Format('PeakWorkingSetSize: %d',[ ppsmemCounters.PeakWorkingSetSize]));
      Writeln( Format('WorkingSetSize: %d',[ ppsmemCounters.WorkingSetSize]));
      Writeln( Format('QuotaPeakPagedPoolUsage: %d',[ ppsmemCounters.QuotaPeakPagedPoolUsage]));
      Writeln( Format('QuotaPagedPoolUsage: %d',[ ppsmemCounters.QuotaPagedPoolUsage]));
      Writeln( Format('QuotaPeakNonPagedPoolUsage: %d',[ ppsmemCounters.QuotaPeakNonPagedPoolUsage]));
      Writeln( Format('PagefileUsage: %d',[ ppsmemCounters.PagefileUsage]));
      Writeln( Format('PeakPagefileUsage: %d',[ ppsmemCounters.PeakPagefileUsage]));
   end;
   finally
     FreeMem(ppsmemCounters);
   end;
  finally
    CloseHandle(hProcess);
  end;
end;

begin
 try
    CoInitialize(nil);
    try
      MemoryInfoService('FirebirdGuardianDefaultInstance');
    finally
      CoUninitialize;
    end;
 except
    on E:EOleException do
        Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;
end.
于 2012-06-25T21:25:19.420 回答
2

我没有特定于 delphi 的代码来执行此操作,但我可以告诉您执行此操作的 windows api 调用(特别是 toolhelp dll 调用)。为此,您需要知道 exe 的名称(不确定这是否适合您)。

  1. 使用createtoolhelp32snapshot,然后使用process32firstprocess32next来定位进程 ID。
  2. 通过将进程 id 传递给OpenProcess来获取进程的句柄
  3. 将进程句柄传递给GetProcessMemoryInfo。这将使用您正在寻找的信息(workingSetSize 结构成员)填充PROCESS_MEMORY_COUNTERS结构。
于 2012-06-25T21:10:40.633 回答
0
  1. 如何从 Delphi 中的服务名称/句柄中找到进程 ID?
  2. GetProcessMemoryInfo找出过程指标
于 2012-06-25T21:11:33.263 回答