有什么方法可以让服务应用程序只知道它的服务名称就使用了多少内存?
问问题
872 次
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 的名称(不确定这是否适合您)。
- 使用createtoolhelp32snapshot,然后使用process32first和process32next来定位进程 ID。
- 通过将进程 id 传递给OpenProcess来获取进程的句柄
- 将进程句柄传递给GetProcessMemoryInfo。这将使用您正在寻找的信息(workingSetSize 结构成员)填充PROCESS_MEMORY_COUNTERS结构。
于 2012-06-25T21:10:40.633 回答
0
于 2012-06-25T21:11:33.263 回答