检测某个程序占用的内存(急) (200分)

G

gztoms

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