프로세스 안에서 CPU / memory 소비량 알아내는 법


어플리케이션을 실행하는 중에 밑의 내용을 알아낼 수 있는 방법이 있을까요?

  • 사용 가능한 virtual memory 크기
  • 지금 쓰고 있는 Virtual memory 크기
  • 이 프로세스가 쓰고 있는 Virtual memory 크기

  • 사용 가능한 RAM 크기
  • 지금 쓰고 있는 RAM 크기
  • 이 프로세스가 쓰고 있는 RAM 크기

  • 지금 CPU 사용률
  • 이 프로세스가 쓰고 있는 CPU 사용률

제 코드는 windows와 linux에서 실행됩니다. 정확한 정보를 얻을 수 없어서 여기에 질문합니다.

  • 2016년 01월 11일에 작성됨

조회수 876


1 답변


좋아요
0
싫어요
채택취소하기

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 MemorygetValue()를 다음과 같이 바꾸세요
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;
}
  • 2016년 01월 11일에 작성됨

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close