프로세스 안에서 CPU / memory 소비량 알아내는 법
조회수 26681회
어플리케이션을 실행하는 중에 밑의 내용을 알아낼 수 있는 방법이 있을까요?
- 사용 가능한 virtual memory 크기
- 지금 쓰고 있는 Virtual memory 크기
- 이 프로세스가 쓰고 있는 Virtual memory 크기
- 사용 가능한 RAM 크기
- 지금 쓰고 있는 RAM 크기
- 이 프로세스가 쓰고 있는 RAM 크기
- 지금 CPU 사용률
- 이 프로세스가 쓰고 있는 CPU 사용률
제 코드는 windows와 linux에서 실행됩니다. 정확한 정보를 얻을 수 없어서 여기에 질문합니다.
1 답변
-
Windows
일부는
WIN32 API
에서 제공하고 있습니다. 그 외의 것은PDH(Performance Data Helper) library
에서 제공합니다.- 전체 Virtual Memory:
#include "windows.h" MEMORYSTATUSEX memInfo; memInfo.dwLength = sizeof(MEMORYSTATUSEX); GlobalMemoryStatusEx(&memInfo); DWORDLONG totalVirtualMem = memInfo.ullTotalPageFile;
TotalPageFile
는 보통swap file
+RAM
을 의미하지만 여기서는 좀 다르게 쓰였습니다.- 지금쓰고 있는 Virtual Memory:
전체 Virtual Memory
에 다음을 추가합니다.
DWORDLONG virtualMemUsed = memInfo.ullTotalPageFile - memInfo.ullAvailPageFile;
- 이 프로세스가 쓰고 있는 Virtual Memory:
#include "windows.h" #include "psapi.h" PROCESS_MEMORY_COUNTERS_EX pmc; GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)); SIZE_T virtualMemUsedByMe = pmc.PrivateUsage;
- 전체 Physical Memory (RAM):
전체 Virtual Memory
에 다음을 추가합니다
DWORDLONG totalPhysMem = memInfo.ullTotalPhys;
- 지금 쓰고 있는 Physical Memory:
전체 Virtual Memory
에 다음을 추가합니다
DWORDLONG physMemUsed = memInfo.ullTotalPhys - memInfo.ullAvailPhys;
- 이 프로세스가 쓰고 있는 Physical Memory:
이 프로세스가 쓰고 있는 Virtual Memory
에 다음을 추가합니다
SIZE_T physMemUsedByMe = pmc.WorkingSetSize;
- 현재 사용 중인 CPU:
#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:
#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
- 전체 Virtual Memory:
#include "sys/types.h" #include "sys/sysinfo.h" struct sysinfo memInfo; sysinfo (&memInfo); long long totalVirtualMem = memInfo.totalram; totalVirtualMem += memInfo.totalswap; totalVirtualMem *= memInfo.mem_unit;
- 지금 쓰고 있는 Virtual Memory:
전체 Virtual Memory
에 다음을 추가합니다.
long long virtualMemUsed = memInfo.totalram - memInfo.freeram; virtualMemUsed += memInfo.totalswap - memInfo.freeswap; virtualMemUsed *= memInfo.mem_unit;
- 이 프로세스가 쓰고 있는 Virtual Memory:
#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(){ //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; }
- 전체 Physical Memory (RAM):
전체 Virtual Memory
에 다음을 추가하세요
long long totalPhysMem = memInfo.totalram; totalPhysMem *= memInfo.mem_unit;
- 지금 쓰고 있는 Physical Memory:
전체 Virtual Memory
에 다음을 추가하세요
long long physMemUsed = memInfo.totalram - memInfo.freeram; physMemUsed *= memInfo.mem_unit;
- 이 프로세스가 쓰고 있는 Physical Memory:
이 프로세스가 쓰고 있는 Virtual Memory
의getValue()
를 다음과 같이 바꾸세요
int getValue(){ //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:
#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 %llu %llu %llu %llu", &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 %llu %llu %llu %llu", &totalUser, &totalUserLow, &totalSys, &totalIdle); fclose(file); if (totalUser < lastTotalUser || totalUserLow < lastTotalUserLow || totalSys < lastTotalSys || totalIdle < lastTotalIdle){ //오버플로우 detection 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:
#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){ //오버플로우 감지 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; }
- 안녕하세요. 작성해주신 코드를 사용해보려 했습니다. PROCESS_MEMORY_COUNTERS_EX pmc;로 선언해주셨는데 GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)); 여기서 중간에 들어갈 파라미터가 &pmc의 형인 PROCESS_MEMORY_COUNTERS_EX가 아니라 PROCESS_MEMORY_COUNTERS라서 맞지 않아 에러가 발생합니다. 알 수 없는 사용자 2018.1.22 16:13
댓글 입력