How to determine CPU and memory consumption from inside a process
来源:互联网 发布:电子商务软件有哪些 编辑:程序博客网 时间:2024/06/07 15:10
- Total virtual memory available
- Virtual memory currently used
- Virtual memory currently used by my process
- Total RAM available
- RAM currently used
- RAM currently used by my process
- % CPU currently used
- % CPU currently used by my process
Windows
Some of the above values are easily available from the appropriate WIN32 API, I just list them here for completeness. Others, however, need to be obtained from the Performance Data Helper libary (PDH), which is a bit "unintuitive" and takes a lot of painful trial and error to get to work. (At least it took me quite a while, perhaps I've been only a bit stupid...)
Note: for clarity all error checking has been omitted from the following code. Do check the return codes...!
- Total Virtual Memory:
#include "windows.h" MEMORYSTATUSEX memInfo; memInfo.dwLength = sizeof(MEMORYSTATUSEX); GlobalMemoryStatusEx(&memInfo); DWORDLONG totalVirtualMem = memInfo.ullTotalPageFile;
Note: The name "TotalPageFile" is a bit misleading here. In reality this parameter gives the "Virtual Memory Size", which is size of swap file plus installed RAM.
- Virtual Memory currently used:
Same code as in "Total Virtual Memory" and then
DWORDLONG virtualMemUsed = memInfo.ullTotalPageFile - memInfo.ullAvailPageFile;
- Virtual Memory currently used by current process:
#include "windows.h" #include "psapi.h" PROCESS_MEMORY_COUNTERS_EX pmc; GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)); SIZE_T virtualMemUsedByMe = pmc.PrivateUsage;
- Total Physical Memory (RAM):
Same code as in "Total Virtual Memory" and then
DWORDLONG totalPhysMem = memInfo.ullTotalPhys;
- Physical Memory currently used:
Same code as in "Total Virtual Memory" and then
DWORDLONG physMemUsed = memInfo.ullTotalPhys - memInfo.ullAvailPhys;
- Physical Memory currently used by current process:
Same code as in "Virtual Memory currently used by current process" and then
SIZE_T physMemUsedByMe = pmc.WorkingSetSize;
- CPU currently used:
#include "TCHAR.h" #include "pdh.h" static PDH_HQUERY cpuQuery; static PDH_HCOUNTER cpuTotal; void init(){ PdhOpenQuery(NULL, NULL, &cpuQuery); PdhAddCounter(cpuQuery, L"\\Processor(_Total)\\% Processor Time", NULL, &cpuTotal); PdhCollectQueryData(cpuQuery); } double getCurrentValue(){ PDH_FMT_COUNTERVALUE counterVal; PdhCollectQueryData(cpuQuery); PdhGetFormattedCounterValue(cpuTotal, PDH_FMT_DOUBLE, NULL, &counterVal); return counterVal.doubleValue; }
- CPU currently used by current process:
#include "windows.h" static ULARGE_INTEGER lastCPU, lastSysCPU, lastUserCPU; static int numProcessors; static HANDLE self; void init(){ SYSTEM_INFO sysInfo; FILETIME ftime, fsys, fuser; GetSystemInfo(&sysInfo); numProcessors = sysInfo.dwNumberOfProcessors; GetSystemTimeAsFileTime(&ftime); memcpy(&lastCPU, &ftime, sizeof(FILETIME)); self = GetCurrentProcess(); GetProcessTimes(self, &ftime, &ftime, &fsys, &fuser); memcpy(&lastSysCPU, &fsys, sizeof(FILETIME)); memcpy(&lastUserCPU, &fuser, sizeof(FILETIME)); } double getCurrentValue(){ FILETIME ftime, fsys, fuser; ULARGE_INTEGER now, sys, user; double percent; GetSystemTimeAsFileTime(&ftime); memcpy(&now, &ftime, sizeof(FILETIME)); GetProcessTimes(self, &ftime, &ftime, &fsys, &fuser); memcpy(&sys, &fsys, sizeof(FILETIME)); memcpy(&user, &fuser, sizeof(FILETIME)); percent = (sys.QuadPart - lastSysCPU.QuadPart) + (user.QuadPart - lastUserCPU.QuadPart); percent /= (now.QuadPart - lastCPU.QuadPart); percent /= numProcessors; lastCPU = now; lastUserCPU = user; lastSysCPU = sys; return percent * 100; }
Linux
On Linux the choice that seemed obvious at first was to use the POSIX APIs like getrusage() etc. I spent some time trying to get this to work, but never got meaningful values. When I finally checked the kernel sources themselves, I found out that apparently these APIs are not yet completely implemented as of Linux kernel 2.6!?
In the end I got all values via a combination of reading the pseudo-filesystem /proc and kernel calls.
- Total Virtual Memory:
#include "sys/types.h" #include "sys/sysinfo.h" struct sysinfo memInfo; sysinfo (&memInfo); long long totalVirtualMem = memInfo.totalram; //Add other values in next statement to avoid int overflow on right hand side... totalVirtualMem += memInfo.totalswap; totalVirtualMem *= memInfo.mem_unit;
- Virtual Memory currently used:
Same code as in "Total Virtual Memory" and then
long long virtualMemUsed = memInfo.totalram - memInfo.freeram; //Add other values in next statement to avoid int overflow on right hand side... virtualMemUsed += memInfo.totalswap - memInfo.freeswap; virtualMemUsed *= memInfo.mem_unit;
- Virtual Memory currently used by current process:
#include "stdlib.h" #include "stdio.h" #include "string.h" int parseLine(char* line){ int i = strlen(line); while (*line < '0' || *line > '9') line++; line[i-3] = '\0'; i = atoi(line); return i; } int getValue(){ //Note: this value is in KB! FILE* file = fopen("/proc/self/status", "r"); int result = -1; char line[128]; while (fgets(line, 128, file) != NULL){ if (strncmp(line, "VmSize:", 7) == 0){ result = parseLine(line); break; } } fclose(file); return result; }
- Total Physical Memory (RAM):
Same code as in "Total Virtual Memory" and then
long long totalPhysMem = memInfo.totalram; //Multiply in next statement to avoid int overflow on right hand side... totalPhysMem *= memInfo.mem_unit;
- Physical Memory currently used:
Same code as in "Total Virtual Memory" and then
long long physMemUsed = memInfo.totalram - memInfo.freeram; //Multiply in next statement to avoid int overflow on right hand side... physMemUsed *= memInfo.mem_unit;
- Physical Memory currently used by current process:
Change getValue() in "Virtual Memory currently used by current process" as follows:
int getValue(){ //Note: this value is in KB! FILE* file = fopen("/proc/self/status", "r"); int result = -1; char line[128]; while (fgets(line, 128, file) != NULL){ if (strncmp(line, "VmRSS:", 6) == 0){ result = parseLine(line); break; } } fclose(file); return result; }
- CPU currently used:
#include "stdlib.h" #include "stdio.h" #include "string.h" static unsigned long long lastTotalUser, lastTotalUserLow, lastTotalSys, lastTotalIdle; void init(){ FILE* file = fopen("/proc/stat", "r"); fscanf(file, "cpu %Ld %Ld %Ld %Ld", &lastTotalUser, &lastTotalUserLow, &lastTotalSys, &lastTotalIdle); fclose(file); } double getCurrentValue(){ double percent; FILE* file; unsigned long long totalUser, totalUserLow, totalSys, totalIdle, total; file = fopen("/proc/stat", "r"); fscanf(file, "cpu %Ld %Ld %Ld %Ld", &totalUser, &totalUserLow, &totalSys, &totalIdle); fclose(file); if (totalUser < lastTotalUser || totalUserLow < lastTotalUserLow || totalSys < lastTotalSys || totalIdle < lastTotalIdle){ //Overflow detection. Just skip this value. percent = -1.0; } else{ total = (totalUser - lastTotalUser) + (totalUserLow - lastTotalUserLow) + (totalSys - lastTotalSys); percent = total; total += (totalIdle - lastTotalIdle); percent /= total; percent *= 100; } lastTotalUser = totalUser; lastTotalUserLow = totalUserLow; lastTotalSys = totalSys; lastTotalIdle = totalIdle; return percent; }
- CPU currently used by current process:
#include "stdlib.h" #include "stdio.h" #include "string.h" #include "sys/times.h" #include "sys/vtimes.h" static clock_t lastCPU, lastSysCPU, lastUserCPU; static int numProcessors; void init(){ FILE* file; struct tms timeSample; char line[128]; lastCPU = times(&timeSample); lastSysCPU = timeSample.tms_stime; lastUserCPU = timeSample.tms_utime; file = fopen("/proc/cpuinfo", "r"); numProcessors = 0; while(fgets(line, 128, file) != NULL){ if (strncmp(line, "processor", 9) == 0) numProcessors++; } fclose(file); } double getCurrentValue(){ struct tms timeSample; clock_t now; double percent; now = times(&timeSample); if (now <= lastCPU || timeSample.tms_stime < lastSysCPU || timeSample.tms_utime < lastUserCPU){ //Overflow detection. Just skip this value. percent = -1.0; } else{ percent = (timeSample.tms_stime - lastSysCPU) + (timeSample.tms_utime - lastUserCPU); percent /= (now - lastCPU); percent /= numProcessors; percent *= 100; } lastCPU = now; lastSysCPU = timeSample.tms_stime; lastUserCPU = timeSample.tms_utime; return percent; }
GlobalMemoryStatus
GlobalMemoryStatus,Win32 API函数。
此函数用来获得当前可用的物理和虚拟内存信息,函数定义为:
1
2
3
4
VOID
GlobalMemoryStatus
(
LPMEMORYSTATUS lpBuffer
);
此函数无返回值,参数是一个指向名为MEMORYSTATUS的结构的指针。函数的返回信息会被存储在MEMORYSTATUS结构中。
此函数用来替代用来支持16位应用程序的GetFreeSpace函数。
2G以上内存建议使用GlobalMemoryStatusEx函数代替(2~4G需要链接器/LARGEADDRESSAWARE选项,4G以上不支持)
应用程序应该在申请内存前调用此函数以防止影响到其他程序运行。
这个函数的返回值是动态的,并且可能返回相同的值。
关于MEMORYSTATUS结构:
结构定义:
1
2
3
4
5
6
7
8
9
10
typedef
struct
_MEMORYSTATUS {
// mst
DWORD
dwLength;
// sizeof(MEMORYSTATUS)
DWORD
dwMemoryLoad;
// percent of memory in use
DWORD
dwTotalPhys;
// bytes of physical memory
DWORD
dwAvailPhys;
// free physical memory bytes
DWORD
dwTotalPageFile;
// bytes of paging file
DWORD
dwAvailPageFile;
// free bytes of paging file
DWORD
dwTotalVirtual;
// user bytes of address space
DWORD
dwAvailVirtual;
// free user bytes
} MEMORYSTATUS, *LPMEMORYSTATUS;
结构成员的含义:
dwLength
MEMORYSTATUS结构的大小,在调GlobalMemoryStatus函数前用sizeof()函数求得,用来供函数检测结构的版本。
dwMemoryLoad
返回一个介于0~100之间的值,用来指示当前系统内存的使用率。
dwTotalPhys
返回总的物理内存大小,以字节(byte)为单位。
dwAvailPhys
返回可用的物理内存大小,以字节(byte)为单位。
dwTotalPageFile
显示可以存在页面文件中的字节数。注意这个数值并不表示在页面文件在磁盘上的真实物理大小。
dwAvailPageFile
返回可用的页面文件大小,以字节(byte)为单位。
dwTotalVirtual
返回调用进程的用户模式部分的全部可用虚拟地址空间,以字节(byte)为单位。
dwAvailVirtual
返回调用进程的用户模式部分的实际自由可用的虚拟地址空间,以字节(byte)为单位。
MEMORYSTATUS结构,
结构的定义如下:
1
2
3
4
5
6
7
8
9
10
MEMORYSTATUS STRUCT
dwLength
DWORD
? ;本结构的长度
dwMemoryLoad
DWORD
? ;已用内存的百分比
dwTotalPhys
DWORD
? ;物理内存总量
dwAvailPhys
DWORD
? ;可用物理内存
dwTotalPageFile
DWORD
? ;交换文件总的大小
dwAvailPageFile
DWORD
? ;交换文件中空闲部分大小
dwTotalVirtual
DWORD
? ;用户可用的地址空间
dwAvailVirtual
DWORD
? ;当前空闲的地址空间
MEMORYSTATUS ENDS
转载地址:http://stackoverflow.com/questions/63166/how-to-determine-cpu-and-memory-consumption-from-inside-a-process
- How to determine CPU and memory consumption from inside a process
- how to calcus a process cpu usage
- experiment: How to determine what services are running under a SVCHOST.EXE process
- How to get an X11 Window from a Process ID?
- Java How to get the PID from a process?
- How to Determine The Lock Type and Mode from an Enqueue Wait
- How to Determine if a file is a .Net assembly (in Delphi and C#)
- FLEX how to reduce the amount of code to reduce memory consumption
- How to spawn a process
- How to determine if a driver should have been registered in kernel and lspci vs pci_device_id
- How To Find Where The Memory Is Growing For A Process (Doc ID 822527.1)
- Identify in details the consumption of memory from a specific session
- [Salesforce] How to determine the login environment from Apex
- how to view bitmaps from memory dump
- SAP HANA memory consumption and license
- How to determine negative number and positive number in Java?
- How to capture error message raised from FM inside
- How to determine if a machine is localhost?
- 【译】CMStepCounter Class Refernce - CoCrash
- 第十一周项目六(3)素数
- 初次接触Android SDK
- Chrome审查元素一些介绍
- CocoaPods安装和使用教程
- How to determine CPU and memory consumption from inside a process
- 第11周项目6回文数素数(1、reverse函数)
- 安卓四大组件的复习——窃听电话(四)
- 使用VNC完成远程调用图形化
- USB OTG驱动分析(一)
- SWIG干了什么
- squid、nginx和lvs
- 深度剖析WordPress主题结构
- 第10周项目4.2大奖赛积分