话题1360311的标题是: 检测某个程序占用的内存(急) (0分)
分类:Windows API gztoms (2002-10-11 15:43:00)
各位大虾:
有谁知道用什么API函数能检测出某一程序占用的内存,
相当于在“任务管理器”里的“进程”叶中所看到的一样。
多谢了!!!
kcahcn (2002-10-10 7:49:00)
任务管理器调用 NtQuerySystemInformation 。还可以用NtQueryInformationProcess.
两者都是本机API(Native API) .
也可以用GetProcessMemoryInfo 包含在PsAPI.
GetPMem(PID
WORD);
var
pmc: PPROCESS_MEMORY_COUNTERS;
cb: Integer;
phandle:Thandle;
begin
phandle:=OpenProcess(PROCESS_ALL_ACCESS,false,PID);
cb := sizeof(_PROCESS_MEMORY_COUNTERS);
GetMem(pmc, cb);
pmc^.cb := cb;
if GetProcessMemoryInfo(phandle, pmc, cb) then
ShowMessage(IntToStr(pmc^.WorkingSetSize))
else
ShowMessage('错误');
end;
gztoms (2002-10-05 17:46:00)
请问kcahcn:
参数PID是要传递什么?
duducat (2002-10-05 19:00:00)
pid 进程ID
kcahcn (2002-10-06 1:11:00)
Thanks duducat .PID -> 进程ID
下面是个用NtQueryInformationProcess的例子 : [ NT ,2K,XP ]
// 参考: Windows NT/2000 本机API (Gary Nebbett)
// Tested using Delphi 6.0, 7.0 On WinXP
type
PVM_Counters=^TVM_Counters;
TVM_Counters=record
PeakVirtualSize:ULONG;
VirtualSize:ULONG;
PagedFaultCount:ULONG;
PeakWorkingSetSize:ULONG;
WorkingSetSize:ULONG;
QuotaPeakPagedPoolUsage:ULONG;
QuotaPagedPoolUsage:ULONG;
QuotaPeakNonPagedPoolUsage:ULONG;
QuotaNonPagedPoolUsage:ULONG;
PagefileUsage:ULONG;
PeakPagefileUsage:ULONG;
end;
const ProcessVMCounters =3;
...
function NtQueryInformationProcess
(
ProcessHandle: Thandle;
PrcInfoClass
WORD ;
PrcInfo
ointer ;
PrcInfoLength:ULONG;
returnlength: TPDword
):
DWORD; stdcall ;external 'ntdll.dll' name 'NtQueryInformationProcess';
// 可以用动态调用(隐式装入)
....
// Our Function here:
function GetPrcVMCounters(PID
WORD):TStringList;
var
status
WORD;
retlen
WORD;
VM_Info:TVM_Counters;
hProcess:THandle;
begin
result:=TStringList.Create;
hProcess :=OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,PID);
status:=NtQueryInformationProcess
(
hProcess,
ProcessVMCounters,
@VM_Info,
sizeof(TVM_Counters),
@retlen
);
if(status<>0) then
begin
ShowMessage('NtQueryInformationProcess 失败');
exit;
end;
with result do
begin
Add('进程虚拟地址空间的最大数值 : '+IntToStr(VM_Info.PeakVirtualSize)+' Byte');
Add('进程的虚拟地址空间的大小 : '+IntToStr(VM_Info.VirtualSize)+' Byte');
Add('进程分页错误数目 : '+IntToStr(VM_Info.PagedFaultCount)+' Byte');
Add('进程的工作集列表的最大值 : '+IntToStr(VM_Info.PeakWorkingSetSize)+' Byte');
Add('进程的工作集列表的大小 : '+IntToStr(VM_Info.WorkingSetSize)+' Byte'); // <--- 就是这个 [
]
Add('填充到进程的分页池的峰值的最大值 : '+IntToStr(VM_Info.QuotaPeakPagedPoolUsage)+' Byte');
Add('填充到进程的分页池的峰值大小 : '+IntToStr(VM_Info.QuotaPagedPoolUsage)+' Byte');
Add('填充到进程的非分页池的峰值的最大值 : '+IntToStr(VM_Info.QuotaNonPagedPoolUsage)+' Byte');
Add('填充到进程的分页池的峰值大小 : '+IntToStr(VM_Info.QuotaNonPagedPoolUsage)+' Byte');
Add('进程多使用的页文件页的最大值 : '+IntToStr(VM_Info.PeakPagefileUsage)+' Byte');
end;
end;
// ----
procedure TForm1.Button2Click(Sender: TObject);
begin
Memo1.Lines:=GetPrcVMCounters(256);
end;
-------------------------
CIONO1
duducat (2002-10-08 8:27:00)
to kcahcn
TPDword=PWORD;
为什么以上方法对PID=0的Idle Process进程占有的物理内存显示不正确??:))
2000下面应该为16K,XP下面是24K,以上方法中GetProcessMemoryInfo显示的是变化的,
数值根本不对,NtQueryInformationProcess则显示的为0!
duducat (2002-10-08 8:32:00)
另外进程CPU占用率也是一个有点技术含量的问题,不知道各位大侠解决没有?
duducat (2002-10-08 8:40:00)
最后9X下面物理内存的使用也是个头痛的问题,嘻嘻……
好像据我所知就TaskInfo2002解决的比较圆满(收费),
prcview(显示不正确)和processwalker则根本没有解决……(免费)
我想这是收费与免费的小小区别吧!
……
题外话,国产的进程管理器俺真是搞不懂,什么技术含量的问题都没有涉及
和解决,就要注册和收注册费了,真是丢中国人的脸……
严重了!!!!!!见谅!
yyk518 (2002-10-08 8:47:00)
做这些东西还有意义吗?技术含量再高,高得过M$吗?[
]
duducat (2002-10-08 9:17:00)
to yyk518
那你永远做MS的最“忠实”用户好了:))好乖亚……
学计算机干吗??对你有意义嘛?
因为你和你的子孙学几百年都不会超过MS的技术高峰的
yyk518 (2002-10-09 8:54:00)
呵呵,这么大火气干嘛呢?
你不也在做MS的忠实用户吗?!你要做的什么破软件不也是要在WINDOWS下运行,舔MS的
屁股吗?有种开发一套DUDUCAT OS出来看看啊!瞎牛B!![
]
duducat (2002-10-09 12:12:00)
白痴……只知道MS……
duducat (2002-10-09 12:43:00)
干吗让我开发os??笑死人了……
我又不是搞电脑的,也不需要靠它来赚钱谋生……
终于知道中国的IT业技术水平为什么这么低,原来是有一些猪头加奴隶充实在当中……
另外,我是人不是牛,人为什么要和牛作比较了,弱智……
做人不知道廉耻,就猪狗不如了……
什么都不知道,还这么神气……佩服佩服呀
哈哈哈哈哈哈哈!!!
天下真是无其不有……哈哈哈哈哈哈
to kcahcn
要讨论技术问题的,以后再跟你联系吧!
yyk518 (2002-10-09 16:19:00)
哦?你不是牛?可我怎么看你都比牛还牛啊!也许,是牛的后代也说不定,哈哈哈
你既然不是搞电脑的,又在这里瞎起什么哄!
知道MS没什么不好吧?!还“中国的IT”呢,谈到IT,不知道MS行吗?蠢猪!!!
呀,别生气啊!竟把猪比作了你(猪听见了可要生气了)
>>什么都不知道,还这么神气
究竟是谁神气了?初出茅庐就不知天高地厚,连MS都不放在眼里了!如果中国人真的能
做出超越MS的软件,我当然非常高兴!但问题是,我们与MS的差距还很大,所以我们必需
好好向人家学习,多做些有益的事!不要两眼向天的走路,那样,你迟早会摔死的!
duducat (2002-10-09 17:01:00)
做人不知道廉耻,就猪狗不如了……
什么都不知道,还这么神气……佩服佩服呀
哈哈哈哈哈哈哈!!!
天下真是无其不有……哈哈哈哈哈哈
duducat (2002-10-09 18:11:00)
教教你吧……人不可有傲气,但不能无傲骨……能者为师
不过你属牛的,跟你说了也不懂,反正是对牛弹琴……
一副奴才像!不过MS好喜欢你的啦,觉得你好哟好可爱哟,呆会买糖给你吃!
(旁白:然后高呼打倒unix,Linux,Java……他们牛个屁呀,能玩服务器,能跨平台嘛?……
嘻嘻,都不如我的MS牛牛牛牛牛(省略5万字)……没有想到太高兴,碰了石头,最后“扑哧”
摔了个狗啃屎……5555555道:“MS,MS,……救救我!!他们说你坏话了,
我要你打他们的小屁股……”然后奋力举起MS掉在粪坑黑乎乎糖,
叫道:“MS的糖是世界最香的糖啦……”, 咬了起来。没想到却是个屁,
还得意的叫道,“MS的屁也是最世界最最香的”……)
当然领导也很喜欢你这种牛了,帮着擦擦皮鞋,拍拍马屁,
赏你个吃“世界上最香的屁”吃吃……哈哈哈哈哈
干吗学电脑了,这又不会那也不会编,又要冒充IT人士,这到没有什么!(人各有所长)
可恶的是还专门打击比那些比你懂得多的人,心理寻思(他会那么多有啥用?
能比XX强嘛?能牛过XX吗?再厉害也不过是个中国人罢了……嘻嘻,
到最后还不如我嘴皮子1/100功效了……)
…………
俺心地善良,以后谁做了大领导一定推荐你这头牛去去拎拎皮鞋哟,呵呵!
编程就免了(即没有创意,又不肯向别人学习……)
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
…………
to 其他各位,对不起了,浪费你们的时间了……
非技术问题,到此为止!
kcahcn (2002-10-10 8:06:00)
对于 system process “系统进程“要先设置SeDebugPrivilege才能用OpenProcess。
飞到这儿: http://support.microsoft.com/default.aspx?scid=kb;en-us;Q131065
用这个方法 对 System Idle Process好像也没有用!!!
TaskManager,Pview 调用的是NtQuerySystemInformation所以没出现这个问题。
我用了那个函数(服务)果然没问题。可以得到System Idle Process所占的内存 (20kb WinXP)。
更多资料关于NtQuerySystemInformation请参考"Windows Nt/2000 本机API"。
关于CPU的占用率可以用GetProcessTimes 。(用Native API 也可以)
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=3816527f.149304919%40nntp.cts.com
看 : http://groups.google.com/groups?q=GetProcessTimes+CPU&ie=UTF-8&oe=UTF-8&hl=en&btnG=Google+Search
-----
CIONO1
yyk518 (2002-10-10 8:32:00)
TO duducat:
呵呵,没想到我随意说说,竟把这头笨牛给惹疯了,前言不搭后语,牛B哄哄地拉了一大堆
牛屎,哈哈哈,我看你不但瞎牛还很蠢,是即有牛的基因又有猪的血统,莫不是猪牛杂交
货?[
][
][
]
duducat (2002-10-10 12:37:00)
垃圾就是垃圾,呵呵,从里到外都是的……
……
to kcahcn
thanx!我说这些问题去年其实已经解决了……只是想讨论一下还有没有别的更好方法!
小日本的Processwalker(免费)
http://www001.upp.so-net.ne.jp/yamashita/
中还实现了其他很多有用的功能,如:进程拥有的特权之类。这些没有实现得了
所以找你的……
交个朋友吧,有空来我这里玩……,呵呵
代我向你妹妹问好……:)
duducat (2002-10-10 21:21:00)
to gztoms
把分加给kcahcnkcahcn,他比我大方……
to kcahcn 再见了……希望以后还有机会跟你联系!我已经把它翻译成Delphi……
我用的不是这个函数!不过我现在有点喜欢NTQuerySystemInformation了!虽然它
存在不稳定因素:P
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef STATUS_INFO_LENGTH_MISMATCH
#define STATUS_INFO_LENGTH_MISMATCH ((DWORD )0xC0000004L)
#endif
typedef struct
{
FILETIME ftCreationTime;
DWORD dwUnknown1;
DWORD dwStartAddress;
DWORD dwOwningPID;
DWORD dwThreadID;
DWORD dwCurrentPriority;
DWORD dwBasePriority;
DWORD dwContextSwitches;
DWORD dwThreadState;
DWORD dwWaitReason;
DWORD dwUnknown2[5];
} THREADINFO, *PTHREADINFO;
#pragma warning( disable:4200 ) // Zero sized array
typedef struct
{
DWORD dwRelativeOffset; //相对偏移量
DWORD dwThreadCount; //线程数目
DWORD dwUnknown1[6];
FILETIME pfCreateTime;
DWORD dwUnknown2[5];
WCHAR* pszProcessName; //不带路径的名称
DWORD dwBasePriority; //优先级
DWORD dwProcessID; //进程ID
DWORD dwParentProcessID; //父进程ID
DWORD dwHandleCount; //句柄数目
DWORD dwUnknown3;
DWORD dwUnknown4;
DWORD dwVirtualBytesPeak;
DWORD dwTotalVirtualBytes;
DWORD dwPageFaults;
DWORD dwWorkingSetPeak;
DWORD dwTotalWorkingSet; //占用物理内存大小
DWORD dwPeakPagedPoolUsagePages;
DWORD dwTotalPagedPoolUsagePages;
DWORD dwPeakNonPagedPoolUsagePages;
DWORD dwTotalNonPagedPoolUsagePages;
DWORD dwPageFileBytesPeak;
DWORD dwPrivateBytes;
DWORD dwPageFileBytes;
DWORD dwUnknown7[4];
THREADINFO ti[0];
} _PROCESSINFO, *PPROCESSINFO;
#pragma warning( default:4200 )
DWORD (__stdcall *NtQuerySystemInformation )(ULONG,PVOID,ULONG,ULONG);
void ShowPI(void)
{
PBYTE pbyInfo = NULL;
PPROCESSINFO pProcessInfo;
DWORD dwSize = 0x4000;
WCHAR *pname;
if (!NtQuerySystemInformation)
NtQuerySystemInformation=(DWORD (__stdcall*)(ULONG,PVOID,ULONG,ULONG))
GetProcAddress(GetModuleHandle("ntdll.dll"
,"NtQuerySystemInformation"
;
pbyInfo=(PBYTE) malloc(dwSize);
if (pbyInfo)
{
for(;
{
memset(pbyInfo,0,dwSize);
if(NtQuerySystemInformation(5,pbyInfo,dwSize,0)!=STATUS_INFO_LENGTH_MISMATCH
)
break;
dwSize += 0x1000;
pbyInfo=(PBYTE) realloc(pbyInfo,dwSize);
}
pProcessInfo = ( PPROCESSINFO ) pbyInfo;
for(;
{
pname=pProcessInfo->pszProcessName;
if (!pname)
pname=(L"Idle"
;
printf("%-40ls %-12lu %12luK/n",
pname,
pProcessInfo->dwProcessID,
pProcessInfo->dwTotalWorkingSet/1024ul
);
if ( pProcessInfo->dwRelativeOffset == 0 )
break;
pProcessInfo=(PPROCESSINFO)((PBYTE)pProcessInfo+pProcessInfo->dwRelativeOffset);
}
free( pbyInfo );
}
}
int main(void)
{
ShowPI();
getchar();
return 0;
}
duducat (2002-10-10 21:28:00)
to gztoms
9X的自己研究吧……实在不知道,明年再联系!
to kcahcn
人生无常,唯朋友最值得珍惜……
kcahcn (2002-10-10 22:17:00)
to duducat : Thanks alot;
我会把我写的代码(经过改进后)发到你的邮箱。(还要一段时间)
NativeAPI有很多东西可以研究。很多人在研究。多多看看Nebbett写的那本书。
有什么冬冬告诉我。[
]
to gztoms :我不是为了积分而回答。我不需要积分。Knowledge is free .
CIONO1
gztoms (2002-10-11 15:43:00)
谢谢kcahcn,duducat