프로세스 내부에서 CPU 및 메모리 사용량을 확인하는 방법은 무엇입니까?
실행중인 응용 프로그램 내부에서 다음과 같은 성능 매개 변수를 결정하는 작업이있었습니다.
- 사용 가능한 총 가상 메모리
- 현재 사용중인 가상 메모리
- 현재 내 프로세스에서 사용하는 가상 메모리
- 사용 가능한 총 RAM
- 현재 사용중인 RAM
- 현재 내 프로세스에서 사용하는 RAM
- 현재 사용중인 CPU 비율
- 내 프로세스에서 현재 사용중인 CPU 비율
코드는 Windows와 Linux에서 실행되어야했습니다. 이것이 표준 작업 인 것처럼 보이지만 매뉴얼 (WIN32 API, GNU 문서)과 인터넷에서 필요한 정보를 찾는 데 며칠이 걸렸습니다.이 주제에 대한 불완전 / 부정확 / 오래된 정보가 너무 많기 때문입니다. 거기에서 찾았습니다.
다른 사람들이 같은 문제를 겪지 않도록하기 위해 흩어져있는 모든 정보와 시행 착오를 통해 찾은 정보를 한곳에 모으는 것이 좋을 것이라고 생각했습니다.
윈도우
위의 값 중 일부는 적절한 WIN32 API에서 쉽게 구할 수 있습니다. 여기서는 완성도를 위해 나열합니다. 그러나 다른 것들은 성능 데이터 도우미 라이브러리 (PDH)에서 얻어야합니다.이 라이브러리는 약간 "직관적이지 않고"작업을 시작하는 데 많은 시행 착오가 필요합니다. (적어도 꽤 오랜 시간이 걸렸는데, 아마 조금 어리 석었을뿐 ...)
참고 : 명확성을 위해 모든 오류 검사는 다음 코드에서 생략되었습니다. 반환 코드를 확인하십시오 ...!
총 가상 메모리 :
#include "windows.h" MEMORYSTATUSEX memInfo; memInfo.dwLength = sizeof(MEMORYSTATUSEX); GlobalMemoryStatusEx(&memInfo); DWORDLONG totalVirtualMem = memInfo.ullTotalPageFile;
참고 : "TotalPageFile"이라는 이름은 여기에서 약간 오해의 소지가 있습니다. 실제로이 매개 변수는 스왑 파일의 크기와 설치된 RAM의 크기 인 "가상 메모리 크기"를 제공합니다.
현재 사용중인 가상 메모리 :
"총 가상 메모리"와 동일한 코드
DWORDLONG virtualMemUsed = memInfo.ullTotalPageFile - memInfo.ullAvailPageFile;
현재 프로세스에서 현재 사용중인 가상 메모리 :
#include "windows.h" #include "psapi.h" PROCESS_MEMORY_COUNTERS_EX pmc; GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)); SIZE_T virtualMemUsedByMe = pmc.PrivateUsage;
총 물리적 메모리 (RAM) :
"총 가상 메모리"와 동일한 코드
DWORDLONG totalPhysMem = memInfo.ullTotalPhys;
현재 사용중인 실제 메모리 :
Same code as in "Total Virtual Memory" and then DWORDLONG physMemUsed = memInfo.ullTotalPhys - memInfo.ullAvailPhys;
현재 프로세스에서 현재 사용중인 실제 메모리 :
"현재 프로세스에서 현재 사용중인 가상 메모리"와 동일한 코드
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); // You can also use L"\\Processor(*)\\% Processor Time" and get individual CPU values with PdhGetFormattedCounterArray() PdhAddEnglishCounter(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에서 처음에는 분명해 보이는 선택은 POSIX API getrusage()
등 을 사용하는 것이 었습니다.이 작업을 수행하기 위해 시간을 보냈지 만 의미있는 값을 얻지 못했습니다. 마침내 커널 소스 자체를 확인했을 때 이러한 API가 아직 Linux 커널 2.6에서 완전히 구현되지 않은 것으로 나타났습니다!?
결국 나는 의사 파일 시스템 /proc
과 커널 호출 을 읽는 조합을 통해 모든 값을 얻었습니다 .
총 가상 메모리 :
#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;
현재 사용중인 가상 메모리 :
"총 가상 메모리"와 동일한 코드
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;
현재 프로세스에서 현재 사용중인 가상 메모리 :
#include "stdlib.h" #include "stdio.h" #include "string.h" int parseLine(char* line){ // This assumes that a digit will be found and the line ends in " Kb". int i = strlen(line); const char* p = line; while (*p <'0' || *p > '9') p++; line[i-3] = '\0'; i = atoi(p); 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; }
총 물리적 메모리 (RAM) :
"총 가상 메모리"와 동일한 코드
long long totalPhysMem = memInfo.totalram; //Multiply in next statement to avoid int overflow on right hand side... totalPhysMem *= memInfo.mem_unit;
현재 사용중인 실제 메모리 :
"총 가상 메모리"와 동일한 코드
long long physMemUsed = memInfo.totalram - memInfo.freeram; //Multiply in next statement to avoid int overflow on right hand side... physMemUsed *= memInfo.mem_unit;
현재 프로세스에서 현재 사용중인 실제 메모리 :
"현재 프로세스에서 현재 사용중인 가상 메모리"의 getValue ()를 다음과 같이 변경합니다.
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 :
#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){ //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 :
#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; }
TODO : 기타 플랫폼
/ proc 의사 파일 시스템을 읽는 부분을 제외하고 Linux 코드 중 일부는 Unix에서도 작동한다고 가정합니다. 아마도 유닉스에서 이러한 부분은 getrusage()
유사한 기능 으로 대체 될 수 있습니까? 유닉스 노하우를 가진 사람이이 답변을 편집하고 세부 사항을 채울 수 있다면?!
맥 OS X
Mac OS X에서도 유사한 정보를 찾고 싶었습니다. 여기 없었기 때문에 나가서 직접 파고 들었습니다. 내가 찾은 것 중 일부는 다음과 같습니다. 누군가 다른 제안이 있으면 듣고 싶습니다.
총 가상 메모리
이것은 Linux와 같은 미리 설정된 스왑 파티션이나 파일을 사용하지 않기 때문에 Mac OS X에서 까다 롭습니다. 다음은 Apple 문서의 항목입니다.
참고 : 대부분의 Unix 기반 운영 체제와 달리 Mac OS X은 가상 메모리에 대해 미리 할당 된 스왑 파티션을 사용하지 않습니다. 대신 컴퓨터의 부팅 파티션에서 사용 가능한 모든 공간을 사용합니다.
따라서 여전히 사용 가능한 가상 메모리의 양을 알고 싶다면 루트 파티션의 크기를 알아야합니다. 다음과 같이 할 수 있습니다.
struct statfs stats;
if (0 == statfs("/", &stats))
{
myFreeSwap = (uint64_t)stats.f_bsize * stats.f_bfree;
}
현재 사용 된 총 가상
"vm.swapusage"키로 systcl을 호출하면 스왑 사용에 대한 흥미로운 정보를 얻을 수 있습니다.
sysctl -n vm.swapusage
vm.swapusage: total = 3072.00M used = 2511.78M free = 560.22M (encrypted)
여기에 표시된 총 스왑 사용량은 위 섹션에서 설명한대로 더 많은 스왑이 필요한 경우 변경 될 수 있습니다. 따라서 총액은 실제로 현재 스왑 총액입니다. C ++에서이 데이터는 다음과 같은 방법으로 쿼리 할 수 있습니다.
xsw_usage vmusage = {0};
size_t size = sizeof(vmusage);
if( sysctlbyname("vm.swapusage", &vmusage, &size, NULL, 0)!=0 )
{
perror( "unable to get swap usage by calling sysctlbyname(\"vm.swapusage\",...)" );
}
sysctl.h에 선언 된 "xsw_usage"는 문서화되지 않은 것처럼 보이며 이러한 값에 액세스하는 더 이식 가능한 방법이 있다고 생각합니다.
내 프로세스에서 현재 사용중인 가상 메모리
task_info
함수를 사용하여 현재 프로세스에 대한 통계를 얻을 수 있습니다 . 여기에는 프로세스의 현재 상주 크기와 현재 가상 크기가 포함됩니다.
#include<mach/mach.h>
struct task_basic_info t_info;
mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
if (KERN_SUCCESS != task_info(mach_task_self(),
TASK_BASIC_INFO, (task_info_t)&t_info,
&t_info_count))
{
return -1;
}
// resident size is in t_info.resident_size;
// virtual size is in t_info.virtual_size;
사용 가능한 총 RAM
시스템에서 사용할 수있는 물리적 RAM의 양은 sysctl
다음과 같은 시스템 기능을 사용하여 사용할 수 있습니다 .
#include <sys/types.h>
#include <sys/sysctl.h>
...
int mib[2];
int64_t physical_memory;
mib[0] = CTL_HW;
mib[1] = HW_MEMSIZE;
length = sizeof(int64_t);
sysctl(mib, 2, &physical_memory, &length, NULL, 0);
현재 사용 된 RAM
host_statistics
시스템 기능 에서 일반 메모리 통계를 얻을 수 있습니다 .
#include <mach/vm_statistics.h>
#include <mach/mach_types.h>
#include <mach/mach_init.h>
#include <mach/mach_host.h>
int main(int argc, const char * argv[]) {
vm_size_t page_size;
mach_port_t mach_port;
mach_msg_type_number_t count;
vm_statistics64_data_t vm_stats;
mach_port = mach_host_self();
count = sizeof(vm_stats) / sizeof(natural_t);
if (KERN_SUCCESS == host_page_size(mach_port, &page_size) &&
KERN_SUCCESS == host_statistics64(mach_port, HOST_VM_INFO,
(host_info64_t)&vm_stats, &count))
{
long long free_memory = (int64_t)vm_stats.free_count * (int64_t)page_size;
long long used_memory = ((int64_t)vm_stats.active_count +
(int64_t)vm_stats.inactive_count +
(int64_t)vm_stats.wire_count) * (int64_t)page_size;
printf("free memory: %lld\nused memory: %lld\n", free_memory, used_memory);
}
return 0;
}
여기서 주목해야 할 점은 Mac OS X에는 5 가지 유형의 메모리 페이지가 있다는 것입니다. 다음과 같습니다.
- 제자리에 잠겨 있고 교체 할 수없는 유선 페이지
- 실제 메모리에로드되고 교체하기가 상대적으로 어려운 활성 페이지
- 메모리에로드되었지만 최근에 사용되지 않았으며 전혀 필요하지 않을 수도있는 비활성 페이지입니다. 이들은 스와핑의 잠재적 인 후보입니다. 이 메모리는 아마도 비워 져야 할 것입니다.
- 쉽게 재사용 할 수있는 캐시 된 페이지입니다. 캐시 된 메모리는 아마도 플러시가 필요하지 않을 것입니다. 캐시 된 페이지를 다시 활성화하는 것은 여전히 가능합니다.
- 완전히 무료이며 사용할 준비가 된 무료 페이지.
Mac OS X가 때때로 실제 사용 가능한 메모리를 거의 표시하지 않기 때문에 짧은 시간에 사용할 준비가 된 양을 나타내는 좋은 표시가 아닐 수 있습니다.
내 프로세스에서 현재 사용중인 RAM
위의 "현재 내 프로세스에서 사용하는 가상 메모리"를 참조하십시오. 동일한 코드가 적용됩니다.
리눅스
Linux에서이 정보는 / proc 파일 시스템에서 사용할 수 있습니다. 각 Linux 배포판이 적어도 하나의 중요한 파일을 사용자 정의하는 것처럼 보이기 때문에 사용되는 텍스트 파일 형식을 좋아하지 않습니다. 'ps'의 소스로 빠르게 살펴보면 혼란이 드러납니다.
그러나 여기에서 원하는 정보를 찾을 수 있습니다.
/ proc / meminfo 에는 사용자가 찾는 대부분의 시스템 정보가 들어 있습니다. 여기 내 시스템처럼 보입니다. MemTotal , MemFree , SwapTotal 및 SwapFree에 관심이 있다고 생각합니다 .
Anderson cxc # more /proc/meminfo
MemTotal: 4083948 kB
MemFree: 2198520 kB
Buffers: 82080 kB
Cached: 1141460 kB
SwapCached: 0 kB
Active: 1137960 kB
Inactive: 608588 kB
HighTotal: 3276672 kB
HighFree: 1607744 kB
LowTotal: 807276 kB
LowFree: 590776 kB
SwapTotal: 2096440 kB
SwapFree: 2096440 kB
Dirty: 32 kB
Writeback: 0 kB
AnonPages: 523252 kB
Mapped: 93560 kB
Slab: 52880 kB
SReclaimable: 24652 kB
SUnreclaim: 28228 kB
PageTables: 2284 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
CommitLimit: 4138412 kB
Committed_AS: 1845072 kB
VmallocTotal: 118776 kB
VmallocUsed: 3964 kB
VmallocChunk: 112860 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
Hugepagesize: 2048 kB
CPU 사용률을 위해 약간의 작업을 수행해야합니다. Linux는 시스템 시작 이후 전체 CPU 사용률을 제공합니다. 이것은 아마도 당신이 관심있는 것이 아닐 것입니다. 마지막 1 초 또는 10 초 동안의 CPU 사용률을 알고 싶다면 정보를 쿼리하고 직접 계산해야합니다.
이 정보는 http://www.linuxhowtos.org/System/procstat.htm에 잘 문서화 되어있는 / proc / stat 에 있습니다 . 다음은 내 4 코어 박스의 모습입니다.
Anderson cxc # more /proc/stat
cpu 2329889 0 2364567 1063530460 9034 9463 96111 0
cpu0 572526 0 636532 265864398 2928 1621 6899 0
cpu1 590441 0 531079 265949732 4763 351 8522 0
cpu2 562983 0 645163 265796890 682 7490 71650 0
cpu3 603938 0 551790 265919440 660 0 9040 0
intr 37124247
ctxt 50795173133
btime 1218807985
processes 116889
procs_running 1
procs_blocked 0
먼저 시스템에서 사용할 수있는 CPU (또는 프로세서 또는 처리 코어) 수를 확인해야합니다. 이렇게하려면 'cpuN'항목의 수를 세십시오. 여기서 N은 0에서 시작하여 증가합니다. cpuN 라인의 조합 인 'cpu'라인을 세지 마십시오. 내 예에서는 총 4 개의 프로세서에 대해 cpu0에서 cpu3까지 볼 수 있습니다. 이제부터는 cpu0..cpu3을 무시하고 'cpu'라인에만 집중할 수 있습니다.
다음으로,이 줄의 네 번째 숫자는 유휴 시간의 척도이므로 'cpu'줄의 네 번째 숫자는 부팅 시간 이후 모든 프로세서의 총 유휴 시간입니다. 이 시간은 각각 1/100 초인 Linux "jiffies"로 측정됩니다.
그러나 총 유휴 시간은 신경 쓰지 않습니다. 주어진 기간 (예 : 마지막 초)의 유휴 시간에 관심이 있습니다. 이 파일을 1 초 간격으로 두 번 읽어야합니다. 그런 다음 줄의 네 번째 값을 비교해 볼 수 있습니다. 예를 들어 샘플을 가져 와서 다음을 얻는 경우 :
cpu 2330047 0 2365006 1063853632 9035 9463 96114 0
그런 다음 1 초 후에이 샘플을 얻습니다.
cpu 2330047 0 2365007 1063854028 9035 9463 96114 0
두 숫자를 빼면 diff가 396이됩니다. 이는 CPU가 마지막 1.00 초 중 3.96 초 동안 유휴 상태 였음을 의미합니다. 물론 비결은 프로세서 수로 나눌 필요가 있다는 것입니다. 3.96 / 4 = 0.99, 유휴 비율이 있습니다. 99 % 유휴 및 1 % 사용 중입니다.
내 코드에는 360 항목의 링 버퍼가 있으며이 파일을 매초마다 읽습니다. 이를 통해 1 초, 10 초 등 최대 1 시간 동안 CPU 사용률을 빠르게 계산할 수 있습니다.
프로세스 별 정보를 보려면 / proc / pid 를 찾아야합니다 . pid에 관심이 없다면 / proc / self를 볼 수 있습니다.
프로세스에서 사용하는 CPU는 / proc / self / stat에 있습니다. 이것은 한 줄로 구성된 이상하게 보이는 파일입니다. 예를 들면 :
19340 (whatever) S 19115 19115 3084 34816 19115 4202752 118200 607 0 0 770 384 2
7 20 0 77 0 266764385 692477952 105074 4294967295 134512640 146462952 321468364
8 3214683328 4294960144 0 2147221247 268439552 1276 4294967295 0 0 17 0 0 0 0
여기에서 중요한 데이터는 13 번째 및 14 번째 토큰입니다 (여기서는 0 및 770). 13 번째 토큰은 프로세스가 사용자 모드에서 실행 한 jiff의 수이고 14 번째는 프로세스가 커널 모드에서 실행 한 jiff의 수입니다. 두 가지를 더하면 총 CPU 사용률이 나타납니다.
다시 말하지만 시간 경과에 따른 프로세스의 CPU 사용량을 확인하려면이 파일을 주기적으로 샘플링하고 차이를 계산해야합니다.
편집 : 프로세스의 CPU 사용률을 계산할 때 1) 프로세스의 스레드 수 및 2) 시스템의 프로세서 수를 고려해야합니다. 예를 들어, 단일 스레드 프로세스가 CPU의 25 % 만 사용하고 있다면 좋을 수도 있고 나쁠 수도 있습니다. 단일 프로세서 시스템에서는 좋지만 4 프로세서 시스템에서는 좋지 않습니다. 이는 프로세스가 지속적으로 실행되고 있으며 사용 가능한 CPU주기의 100 %를 사용함을 의미합니다.
프로세스 별 메모리 정보의 경우 다음과 같은 / proc / self / status를 확인해야합니다.
Name: whatever
State: S (sleeping)
Tgid: 19340
Pid: 19340
PPid: 19115
TracerPid: 0
Uid: 0 0 0 0
Gid: 0 0 0 0
FDSize: 256
Groups: 0 1 2 3 4 6 10 11 20 26 27
VmPeak: 676252 kB
VmSize: 651352 kB
VmLck: 0 kB
VmHWM: 420300 kB
VmRSS: 420296 kB
VmData: 581028 kB
VmStk: 112 kB
VmExe: 11672 kB
VmLib: 76608 kB
VmPTE: 1244 kB
Threads: 77
SigQ: 0/36864
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: fffffffe7ffbfeff
SigIgn: 0000000010001000
SigCgt: 20000001800004fc
CapInh: 0000000000000000
CapPrm: 00000000ffffffff
CapEff: 00000000fffffeff
Cpus_allowed: 0f
Mems_allowed: 1
voluntary_ctxt_switches: 6518
nonvoluntary_ctxt_switches: 6598
'Vm'으로 시작하는 항목은 흥미로운 항목입니다.
- VmPeak 은 프로세스에서 사용하는 최대 가상 메모리 공간 (kB (1024 바이트))입니다.
- VmSize 는 프로세스에서 사용하는 현재 가상 메모리 공간 (kB)입니다. 제 예에서는 651,352 kB 또는 약 636 메가 바이트로 꽤 큽니다.
- VmRss 는 프로세스의 주소 공간 또는 상주 세트 크기에 매핑 된 메모리의 양입니다. 이것은 훨씬 더 작습니다 (420,296kB 또는 약 410 메가 바이트). 차이점 : 내 프로그램은 mmap ()을 통해 636MB를 매핑했지만 410MB 만 액세스했기 때문에 410MB의 페이지 만 할당되었습니다.
내가 확실하지 않은 유일한 항목은 현재 내 프로세스에서 사용하는 Swapspace 입니다. 이것이 가능한지 모르겠습니다.
Windows에서는 다음 코드로 CPU 사용량을 얻을 수 있습니다.
#include <windows.h>
#include <stdio.h>
//------------------------------------------------------------------------------------------------------------------
// Prototype(s)...
//------------------------------------------------------------------------------------------------------------------
CHAR cpuusage(void);
//-----------------------------------------------------
typedef BOOL ( __stdcall * pfnGetSystemTimes)( LPFILETIME lpIdleTime, LPFILETIME lpKernelTime, LPFILETIME lpUserTime );
static pfnGetSystemTimes s_pfnGetSystemTimes = NULL;
static HMODULE s_hKernel = NULL;
//-----------------------------------------------------
void GetSystemTimesAddress()
{
if( s_hKernel == NULL )
{
s_hKernel = LoadLibrary( L"Kernel32.dll" );
if( s_hKernel != NULL )
{
s_pfnGetSystemTimes = (pfnGetSystemTimes)GetProcAddress( s_hKernel, "GetSystemTimes" );
if( s_pfnGetSystemTimes == NULL )
{
FreeLibrary( s_hKernel ); s_hKernel = NULL;
}
}
}
}
//----------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------
// cpuusage(void)
// ==============
// Return a CHAR value in the range 0 - 100 representing actual CPU usage in percent.
//----------------------------------------------------------------------------------------------------------------
CHAR cpuusage()
{
FILETIME ft_sys_idle;
FILETIME ft_sys_kernel;
FILETIME ft_sys_user;
ULARGE_INTEGER ul_sys_idle;
ULARGE_INTEGER ul_sys_kernel;
ULARGE_INTEGER ul_sys_user;
static ULARGE_INTEGER ul_sys_idle_old;
static ULARGE_INTEGER ul_sys_kernel_old;
static ULARGE_INTEGER ul_sys_user_old;
CHAR usage = 0;
// we cannot directly use GetSystemTimes on C language
/* add this line :: pfnGetSystemTimes */
s_pfnGetSystemTimes(&ft_sys_idle, /* System idle time */
&ft_sys_kernel, /* system kernel time */
&ft_sys_user); /* System user time */
CopyMemory(&ul_sys_idle , &ft_sys_idle , sizeof(FILETIME)); // Could been optimized away...
CopyMemory(&ul_sys_kernel, &ft_sys_kernel, sizeof(FILETIME)); // Could been optimized away...
CopyMemory(&ul_sys_user , &ft_sys_user , sizeof(FILETIME)); // Could been optimized away...
usage =
(
(
(
(
(ul_sys_kernel.QuadPart - ul_sys_kernel_old.QuadPart)+
(ul_sys_user.QuadPart - ul_sys_user_old.QuadPart)
)
-
(ul_sys_idle.QuadPart-ul_sys_idle_old.QuadPart)
)
*
(100)
)
/
(
(ul_sys_kernel.QuadPart - ul_sys_kernel_old.QuadPart)+
(ul_sys_user.QuadPart - ul_sys_user_old.QuadPart)
)
);
ul_sys_idle_old.QuadPart = ul_sys_idle.QuadPart;
ul_sys_user_old.QuadPart = ul_sys_user.QuadPart;
ul_sys_kernel_old.QuadPart = ul_sys_kernel.QuadPart;
return usage;
}
//------------------------------------------------------------------------------------------------------------------
// Entry point
//------------------------------------------------------------------------------------------------------------------
int main(void)
{
int n;
GetSystemTimesAddress();
for(n=0;n<20;n++)
{
printf("CPU Usage: %3d%%\r",cpuusage());
Sleep(2000);
}
printf("\n");
return 0;
}
리눅스
메모리를 읽고 번호를로드하는 휴대용 방법은 sysinfo
호출입니다.
용법
#include <sys/sysinfo.h>
int sysinfo(struct sysinfo *info);
기술
Until Linux 2.3.16, sysinfo() used to return information in the
following structure:
struct sysinfo {
long uptime; /* Seconds since boot */
unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
unsigned long totalram; /* Total usable main memory size */
unsigned long freeram; /* Available memory size */
unsigned long sharedram; /* Amount of shared memory */
unsigned long bufferram; /* Memory used by buffers */
unsigned long totalswap; /* Total swap space size */
unsigned long freeswap; /* swap space still available */
unsigned short procs; /* Number of current processes */
char _f[22]; /* Pads structure to 64 bytes */
};
and the sizes were given in bytes.
Since Linux 2.3.23 (i386), 2.3.48 (all architectures) the structure
is:
struct sysinfo {
long uptime; /* Seconds since boot */
unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
unsigned long totalram; /* Total usable main memory size */
unsigned long freeram; /* Available memory size */
unsigned long sharedram; /* Amount of shared memory */
unsigned long bufferram; /* Memory used by buffers */
unsigned long totalswap; /* Total swap space size */
unsigned long freeswap; /* swap space still available */
unsigned short procs; /* Number of current processes */
unsigned long totalhigh; /* Total high memory size */
unsigned long freehigh; /* Available high memory size */
unsigned int mem_unit; /* Memory unit size in bytes */
char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding to 64 bytes */
};
and the sizes are given as multiples of mem_unit bytes.
QNX
이것은 "코드의 위키 페이지"와 같기 때문에 QNX 지식베이스에서 일부 코드를 추가하고 싶습니다 (참고 : 이것은 내 작업이 아니지만 확인했고 내 시스템에서 잘 작동합니다).
%로 CPU 사용량을 얻는 방법 : http://www.qnx.com/support/knowledgebase.html?id=50130000000P9b5
#include <atomic.h>
#include <libc.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/iofunc.h>
#include <sys/neutrino.h>
#include <sys/resmgr.h>
#include <sys/syspage.h>
#include <unistd.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/debug.h>
#include <sys/procfs.h>
#include <sys/syspage.h>
#include <sys/neutrino.h>
#include <sys/time.h>
#include <time.h>
#include <fcntl.h>
#include <devctl.h>
#include <errno.h>
#define MAX_CPUS 32
static float Loads[MAX_CPUS];
static _uint64 LastSutime[MAX_CPUS];
static _uint64 LastNsec[MAX_CPUS];
static int ProcFd = -1;
static int NumCpus = 0;
int find_ncpus(void) {
return NumCpus;
}
int get_cpu(int cpu) {
int ret;
ret = (int)Loads[ cpu % MAX_CPUS ];
ret = max(0,ret);
ret = min(100,ret);
return( ret );
}
static _uint64 nanoseconds( void ) {
_uint64 sec, usec;
struct timeval tval;
gettimeofday( &tval, NULL );
sec = tval.tv_sec;
usec = tval.tv_usec;
return( ( ( sec * 1000000 ) + usec ) * 1000 );
}
int sample_cpus( void ) {
int i;
debug_thread_t debug_data;
_uint64 current_nsec, sutime_delta, time_delta;
memset( &debug_data, 0, sizeof( debug_data ) );
for( i=0; i<NumCpus; i++ ) {
/* Get the sutime of the idle thread #i+1 */
debug_data.tid = i + 1;
devctl( ProcFd, DCMD_PROC_TIDSTATUS,
&debug_data, sizeof( debug_data ), NULL );
/* Get the current time */
current_nsec = nanoseconds();
/* Get the deltas between now and the last samples */
sutime_delta = debug_data.sutime - LastSutime[i];
time_delta = current_nsec - LastNsec[i];
/* Figure out the load */
Loads[i] = 100.0 - ( (float)( sutime_delta * 100 ) / (float)time_delta );
/* Flat out strange rounding issues. */
if( Loads[i] < 0 ) {
Loads[i] = 0;
}
/* Keep these for reference in the next cycle */
LastNsec[i] = current_nsec;
LastSutime[i] = debug_data.sutime;
}
return EOK;
}
int init_cpu( void ) {
int i;
debug_thread_t debug_data;
memset( &debug_data, 0, sizeof( debug_data ) );
/* Open a connection to proc to talk over.*/
ProcFd = open( "/proc/1/as", O_RDONLY );
if( ProcFd == -1 ) {
fprintf( stderr, "pload: Unable to access procnto: %s\n",strerror( errno ) );
fflush( stderr );
return -1;
}
i = fcntl(ProcFd,F_GETFD);
if(i != -1){
i |= FD_CLOEXEC;
if(fcntl(ProcFd,F_SETFD,i) != -1){
/* Grab this value */
NumCpus = _syspage_ptr->num_cpu;
/* Get a starting point for the comparisons */
for( i=0; i<NumCpus; i++ ) {
/*
* the sutime of idle thread is how much
* time that thread has been using, we can compare this
* against how much time has passed to get an idea of the
* load on the system.
*/
debug_data.tid = i + 1;
devctl( ProcFd, DCMD_PROC_TIDSTATUS, &debug_data, sizeof( debug_data ), NULL );
LastSutime[i] = debug_data.sutime;
LastNsec[i] = nanoseconds();
}
return(EOK);
}
}
close(ProcFd);
return(-1);
}
void close_cpu(void){
if(ProcFd != -1){
close(ProcFd);
ProcFd = -1;
}
}
int main(int argc, char* argv[]){
int i,j;
init_cpu();
printf("System has: %d CPUs\n", NumCpus);
for(i=0; i<20; i++) {
sample_cpus();
for(j=0; j<NumCpus;j++)
printf("CPU #%d: %f\n", j, Loads[j]);
sleep(1);
}
close_cpu();
}
무료 (!) 메모리를 얻는 방법 : http://www.qnx.com/support/knowledgebase.html?id=50130000000mlbx
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <err.h>
#include <sys/stat.h>
#include <sys/types.h>
int main( int argc, char *argv[] ){
struct stat statbuf;
paddr_t freemem;
stat( "/proc", &statbuf );
freemem = (paddr_t)statbuf.st_size;
printf( "Free memory: %d bytes\n", freemem );
printf( "Free memory: %d KB\n", freemem / 1024 );
printf( "Free memory: %d MB\n", freemem / ( 1024 * 1024 ) );
return 0;
}
Mac OS X-CPU
전체 CPU 사용량 :
MacOS X에서 시스템 정보 검색 에서 ? :
#include <mach/mach_init.h>
#include <mach/mach_error.h>
#include <mach/mach_host.h>
#include <mach/vm_map.h>
static unsigned long long _previousTotalTicks = 0;
static unsigned long long _previousIdleTicks = 0;
// Returns 1.0f for "CPU fully pinned", 0.0f for "CPU idle", or somewhere in between
// You'll need to call this at regular intervals, since it measures the load between
// the previous call and the current one.
float GetCPULoad()
{
host_cpu_load_info_data_t cpuinfo;
mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
if (host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t)&cpuinfo, &count) == KERN_SUCCESS)
{
unsigned long long totalTicks = 0;
for(int i=0; i<CPU_STATE_MAX; i++) totalTicks += cpuinfo.cpu_ticks[i];
return CalculateCPULoad(cpuinfo.cpu_ticks[CPU_STATE_IDLE], totalTicks);
}
else return -1.0f;
}
float CalculateCPULoad(unsigned long long idleTicks, unsigned long long totalTicks)
{
unsigned long long totalTicksSinceLastTime = totalTicks-_previousTotalTicks;
unsigned long long idleTicksSinceLastTime = idleTicks-_previousIdleTicks;
float ret = 1.0f-((totalTicksSinceLastTime > 0) ? ((float)idleTicksSinceLastTime)/totalTicksSinceLastTime : 0);
_previousTotalTicks = totalTicks;
_previousIdleTicks = idleTicks;
return ret;
}
내 C ++ 프로젝트에서 다음 코드를 사용했는데 제대로 작동했습니다.
static HANDLE self;
static int numProcessors;
SYSTEM_INFO sysInfo;
double percent;
numProcessors = sysInfo.dwNumberOfProcessors;
//Getting system times information
FILETIME SysidleTime;
FILETIME SyskernelTime;
FILETIME SysuserTime;
ULARGE_INTEGER SyskernelTimeInt, SysuserTimeInt;
GetSystemTimes(&SysidleTime, &SyskernelTime, &SysuserTime);
memcpy(&SyskernelTimeInt, &SyskernelTime, sizeof(FILETIME));
memcpy(&SysuserTimeInt, &SysuserTime, sizeof(FILETIME));
__int64 denomenator = SysuserTimeInt.QuadPart + SyskernelTimeInt.QuadPart;
//Getting process times information
FILETIME ProccreationTime, ProcexitTime, ProcKernelTime, ProcUserTime;
ULARGE_INTEGER ProccreationTimeInt, ProcexitTimeInt, ProcKernelTimeInt, ProcUserTimeInt;
GetProcessTimes(self, &ProccreationTime, &ProcexitTime, &ProcKernelTime, &ProcUserTime);
memcpy(&ProcKernelTimeInt, &ProcKernelTime, sizeof(FILETIME));
memcpy(&ProcUserTimeInt, &ProcUserTime, sizeof(FILETIME));
__int64 numerator = ProcUserTimeInt.QuadPart + ProcKernelTimeInt.QuadPart;
//QuadPart represents a 64-bit signed integer (ULARGE_INTEGER)
percent = 100*(numerator/denomenator);
Linux의 경우 / proc / self / statm을 사용하여 주요 프로세스 메모리 정보를 포함하는 한 줄의 숫자를 얻을 수 있습니다. 이는 proc / self / status에서 얻을 때보고 된 정보의 긴 목록을 살펴 보는 것보다 처리하는 것이 더 빠릅니다.
See http://man7.org/linux/man-pages/man5/proc.5.html
/proc/[pid]/statm
Provides information about memory usage, measured in pages.
The columns are:
size (1) total program size
(same as VmSize in /proc/[pid]/status)
resident (2) resident set size
(same as VmRSS in /proc/[pid]/status)
shared (3) number of resident shared pages (i.e., backed by a file)
(same as RssFile+RssShmem in /proc/[pid]/status)
text (4) text (code)
lib (5) library (unused since Linux 2.6; always 0)
data (6) data + stack
dt (7) dirty pages (unused since Linux 2.6; always 0)
'IT박스' 카테고리의 다른 글
WPF에서 x : Name 및 Name 특성의 차이점은 무엇입니까? (0) | 2020.10.04 |
---|---|
( 'b'+ 'a'+ + 'a'+ 'a'). toLowerCase () 'banana'의 결과는 무엇입니까? (0) | 2020.10.04 |
내 프로그램이 충돌 할 때 자동으로 스택 추적을 생성하는 방법 (0) | 2020.10.04 |
값에 대해 여러 변수를 테스트하는 방법은 무엇입니까? (0) | 2020.10.03 |
PHP에서 문자열의 모든 공백을 어떻게 제거합니까? (0) | 2020.10.03 |