วิธีการคำนวณปริมาณการใช้ CPU และหน่วยความจำจากภายในกระบวนการ?


593

ฉันเคยมีหน้าที่กำหนดพารามิเตอร์ประสิทธิภาพต่อไปนี้จากภายในแอปพลิเคชันที่ทำงานอยู่:

  • หน่วยความจำเสมือนทั้งหมดที่มี
  • หน่วยความจำเสมือนที่ใช้อยู่ในปัจจุบัน
  • หน่วยความจำเสมือนที่กระบวนการของฉันใช้อยู่ในปัจจุบัน
  • RAM ทั้งหมดที่มี
  • RAM ที่ใช้ในปัจจุบัน
  • RAM ที่กระบวนการของฉันใช้อยู่ในปัจจุบัน
  • % CPU ที่ใช้อยู่ในปัจจุบัน
  • % CPU ที่กระบวนการของฉันใช้อยู่ในปัจจุบัน

รหัสต้องทำงานบน Windows และ Linux แม้ว่านี่จะเป็นงานมาตรฐาน แต่การค้นหาข้อมูลที่จำเป็นในคู่มือ (WIN32 API, เอกสาร GNU) และบนอินเทอร์เน็ตใช้เวลาหลายวันเพราะมีข้อมูลที่ไม่สมบูรณ์ / ไม่ถูกต้อง / ล้าสมัยในหัวข้อนี้ พบว่ามี

เพื่อช่วยผู้อื่นให้พ้นจากปัญหาเดียวกันฉันคิดว่าเป็นความคิดที่ดีที่จะรวบรวมข้อมูลที่กระจัดกระจายทั้งหมดรวมถึงสิ่งที่ฉันพบจากการลองผิดลองถูกที่นี่ในที่เดียว


13
"หน่วยความจำเสมือนทั้งหมดที่มี" เป็นความหมายในระบบปฏิบัติการสมัยใหม่
David Schwartz

29
ทำไมมันไม่มีความหมาย? มันทำให้คำตอบที่นี่เป็นโมฆะหรือไม่ stackoverflow.com/questions/3296211/… ... โปรดอย่าทิ้งความตื่นเต้นเมื่อแสดงความคิดเห็นมันไม่ใช่รายการทีวี
Mindaugas Bernatavičius

3
@ MindaugasBernatavičius: คำถามที่เชื่อมโยงนั้นเกี่ยวกับ "หน่วยความจำกายภาพทั้งหมด" ซึ่งเป็นข้อเท็จจริงเกี่ยวกับฮาร์ดแวร์ที่รู้จักกันในระบบปฏิบัติการ คุณจะได้รับผลรวมโดยการเพิ่มขนาดของโมดูลหน่วยความจำทั้งหมด "หน่วยความจำเสมือนทั้งหมดที่มี" ในทางกลับกันนั่นหมายความว่ายังไง? นั่นคือการรวมพื้นที่ที่อยู่เสมือนของกระบวนการทั้งหมดที่สร้างขึ้นตามหลักวิชาหรือไม่? ตัวเลขนั้นจะอยู่ที่ประมาณ 2 ^ 80 ไบต์จึงไม่มีความหมายอย่างแน่นอน
MSalters

2
@MSalters - ขอบคุณสำหรับการมีส่วนร่วม ฉันเชื่อว่าการถามสิ่งที่ผู้ปฏิบัติงานมีอยู่ในใจเป็นคนใจดีและมีสุขภาพดีกว่าที่ระบุว่าบางสิ่งไม่มีความหมาย (ไม่มีคำอธิบาย) หากคุณทราบคำตอบจะถือว่าตำแหน่งเฉพาะเกี่ยวกับเรื่องนี้: หน่วยความจำเสมือน = RAM + SWAP (หรือ PAGEFILE) - ซึ่งเป็นข้อสมมติที่สมเหตุสมผล จากนี้เรารู้ว่ามันไม่มีความหมายเนื่องจากมีการตีความเฉพาะของคำนี้ (ซึ่งอาจไม่ถูกต้องที่สุดในทางเทคนิคเป็นภาษาพูด) ที่มีความหมาย
Mindaugas Bernatavičius

2
@ MindaugasBernatavičius: ไม่สนใจไฟล์และรหัสที่แมปหน่วยความจำซึ่งไม่สามารถทำเพจได้ลินุกซ์มีการจัดสรรหน่วยความจำที่ไม่มุ่งมั่น (ไม่ได้รับการสนับสนุนจาก RAM หรือ swap) และ Windows มีสแต็ค
MSalters

คำตอบ:


644

ของ windows

ค่าบางอย่างข้างต้นสามารถใช้งานได้อย่างง่ายดายจาก WIN32 API ที่เหมาะสมฉันเพิ่งแสดงรายการไว้ที่นี่เพื่อความสมบูรณ์ อย่างไรก็ตามคนอื่น ๆ จำเป็นต้องได้รับจาก Performance Data Helper library (PDH) ซึ่งเป็นบิตที่ "ไม่สามารถใช้งานได้" และต้องใช้การทดลองและข้อผิดพลาดที่เจ็บปวดจำนวนมากเพื่อไปทำงาน (อย่างน้อยฉันก็ใช้เวลาพักนึงบางทีฉันอาจจะโง่ไปนิดหน่อย ... )

หมายเหตุ: เพื่อความชัดเจนการตรวจสอบข้อผิดพลาดทั้งหมดถูกละเว้นจากรหัสต่อไปนี้ ตรวจสอบรหัสส่งคืน ... !


  • หน่วยความจำเสมือนทั้งหมด:

    #include "windows.h"
    
    MEMORYSTATUSEX memInfo;
    memInfo.dwLength = sizeof(MEMORYSTATUSEX);
    GlobalMemoryStatusEx(&memInfo);
    DWORDLONG totalVirtualMem = memInfo.ullTotalPageFile;

    หมายเหตุ: ชื่อ "TotalPageFile" ทำให้เข้าใจผิดเล็กน้อยที่นี่ ในความเป็นจริงพารามิเตอร์นี้ให้ "ขนาดหน่วยความจำเสมือน" ซึ่งเป็นขนาดของไฟล์สลับพร้อม RAM ที่ติดตั้ง

  • หน่วยความจำเสมือนที่ใช้อยู่ในปัจจุบัน:

    รหัสเดียวกันใน "Total Virtual Memory" จากนั้น

    DWORDLONG virtualMemUsed = memInfo.ullTotalPageFile - memInfo.ullAvailPageFile;
  • หน่วยความจำเสมือนที่ใช้โดยกระบวนการปัจจุบัน:

    #include "windows.h"
    #include "psapi.h"
    
    PROCESS_MEMORY_COUNTERS_EX pmc;
    GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc));
    SIZE_T virtualMemUsedByMe = pmc.PrivateUsage;



  • หน่วยความจำกายภาพทั้งหมด (RAM):

    รหัสเดียวกันใน "Total Virtual Memory" จากนั้น

    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 kernel 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;
  • หน่วยความจำเสมือนที่ใช้อยู่ในปัจจุบัน:

    รหัสเดียวกันใน "Total Virtual Memory" จากนั้น

    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):

    รหัสเดียวกันใน "Total Virtual Memory" จากนั้น

    long long totalPhysMem = memInfo.totalram;
    //Multiply in next statement to avoid int overflow on right hand side...
    totalPhysMem *= memInfo.mem_unit;
  • หน่วยความจำกายภาพที่ใช้อยู่ในปัจจุบัน:

    รหัสเดียวกันใน "Total Virtual Memory" จากนั้น

    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;
    }

สิ่งที่ต้องทำ: แพลตฟอร์มอื่น ๆ

ฉันสมมติว่ารหัส Linux บางตัวยังทำงานได้กับ Unixes ยกเว้นส่วนที่อ่าน / proc pseudo-filesystem บางทีในระบบปฏิบัติการยูนิกซ์ชิ้นส่วนเหล่านี้สามารถถูกแทนที่ด้วยgetrusage()และฟังก์ชั่นที่คล้ายกัน? หากใครที่มีความรู้เกี่ยวกับ Unix สามารถแก้ไขคำตอบนี้และกรอกรายละเอียดได้!


10
คำเตือน: ใน PdhAddCounter แบบสอบถามต้องเป็นภาษาท้องถิ่นมิฉะนั้นจะทำงานเฉพาะในระบบภาษาอังกฤษเท่านั้น สำหรับ Vista / 2008 และระบบใหม่กว่าให้ใช้ PdhAddEnglishCounter เพื่อหลีกเลี่ยงปัญหาการแปล
moala

2
@NunoAniceto เมื่อใช้PROCESS_MEMORY_COUNTERSคุณจะดึง "หน่วยความจำเสมือนที่ใช้โดยกระบวนการปัจจุบัน" ได้อย่างไร? PrivateUsageไม่ใช่สมาชิกของPROCESS_MEMORY_COUNTERSเป็นข้อผิดพลาดของคอมไพเลอร์ที่ฉันได้รับ!
CinCout

2
เหตุใดคุณจึงใช้"quotes like these"เพื่อรวมส่วนหัวของระบบ
การแข่งขัน Lightness ใน Orbit

8
@CinCout คุณต้องการการคัดลอก .. แทนที่ GetProcessMemoryInfo (GetCurrentProcess (), & pmc, sizeof (pmc)); ด้วย GetProcessMemoryInfo (GetCurrentProcess (), (PROCESS_MEMORY_COUNTERS *) & pmc, ขนาดของ (pmc));
Sumia

3
@ Lanelot เนื่องจากเราอยู่เหนือ Linux Kernel 3.0 คุณสามารถอัปเดตคำตอบ Linux เป็น POSIX API ได้หรือไม่ หากเป็นไปได้ให้แก้ไขคำตอบของ Windows ด้วยเช่นกันโดยแทนที่GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc));ด้วยGetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc));
Dr. Xperience

140

Mac OS X

ฉันหวังว่าจะพบข้อมูลที่คล้ายกันสำหรับ Mac OS X เช่นกัน เนื่องจากมันไม่ได้อยู่ที่นี่ฉันจึงออกไปขุดเอง นี่คือบางสิ่งที่ฉันพบ หากใครมีข้อเสนอแนะอื่น ๆ ฉันชอบที่จะได้ยินพวกเขา

หน่วยความจำเสมือนทั้งหมด

อันนี้มีความยุ่งยากใน Mac OS X เพราะมันไม่ได้ใช้พาร์ทิชัน swap ที่ตั้งไว้หรือไฟล์เช่น Linux นี่คือรายการจากเอกสารของ Apple:

หมายเหตุ:ซึ่งแตกต่างจากระบบปฏิบัติการที่ใช้ Unix ส่วนใหญ่ Mac OS X ไม่ได้ใช้พาร์ทิชัน swap ที่จัดสรรล่วงหน้าสำหรับหน่วยความจำเสมือน แต่จะใช้พื้นที่ที่มีอยู่ทั้งหมดบนพาร์ติชันสำหรับบูตของเครื่องแทน

ดังนั้นถ้าคุณต้องการทราบจำนวนหน่วยความจำเสมือนที่ยังคงมีอยู่คุณต้องได้ขนาดพาร์ติชันรูท คุณสามารถทำสิ่งนี้ได้:

struct statfs stats;
if (0 == statfs("/", &stats))
{
    myFreeSwap = (uint64_t)stats.f_bsize * stats.f_bfree;
}

รวมเสมือนที่ใช้อยู่ในปัจจุบัน

การเรียก systcl ด้วยปุ่ม "vm.swapusage" ให้ข้อมูลที่น่าสนใจเกี่ยวกับการใช้ swap:

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\",...)" );
}

โปรดทราบว่า "xsw_usage" ซึ่งประกาศใน sysctl.h ดูเหมือนว่าจะไม่มีการจัดทำเป็นเอกสารและฉันสงสัยว่ามีวิธีที่สะดวกกว่าในการเข้าถึงค่าเหล่านี้

หน่วยความจำเสมือนที่กระบวนการของฉันใช้อยู่ในปัจจุบัน

คุณสามารถรับสถิติเกี่ยวกับกระบวนการปัจจุบันของคุณโดยใช้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 มีดังนี้:

  1. หน้าแบบมีสายที่ถูกล็อคเข้าที่และไม่สามารถสลับออกได้
  2. เพจที่แอ็คทีฟที่โหลดลงในหน่วยความจำกายภาพและค่อนข้างยากที่จะสลับออก
  3. หน้าที่ไม่ได้ใช้งานซึ่งถูกโหลดเข้าสู่หน่วยความจำ แต่ไม่ได้ใช้งานเมื่อเร็ว ๆ นี้และอาจไม่จำเป็นเลย สิ่งเหล่านี้คือตัวเลือกที่มีศักยภาพสำหรับการแลกเปลี่ยน อาจต้องล้างหน่วยความจำนี้
  4. หน้าที่แคชซึ่งเป็นวิธีที่แคชที่น่าจะนำมาใช้ซ้ำได้ง่าย หน่วยความจำแคชอาจไม่จำเป็นต้องล้างออก ยังคงเป็นไปได้ที่หน้าแคชจะเปิดใช้งานอีกครั้ง
  5. หน้าฟรีที่สมบูรณ์ฟรีและพร้อมใช้งาน

เป็นเรื่องที่ดีที่จะต้องทราบว่าเพียงเพราะ Mac OS X อาจแสดงหน่วยความจำว่างที่เกิดขึ้นจริงน้อยมากในบางครั้งซึ่งอาจไม่บ่งบอกว่ามีความพร้อมที่จะใช้เมื่อมีการแจ้งเตือนสั้น ๆ

RAM ที่กระบวนการของฉันใช้อยู่ในปัจจุบัน

ดู "หน่วยความจำเสมือนที่กระบวนการของฉันใช้อยู่ในปัจจุบัน" ด้านบน ใช้รหัสเดียวกัน


คุณออกจาก #include <mach / mach.h> เพื่อกำหนด task_info () ในส่วน "หน่วยความจำเสมือนที่ใช้โดยกระบวนการของฉันในปัจจุบัน" ส่วนหัวนี้จะต้องรวมไว้เพื่อกำหนดฟังก์ชั่นนั้น
Dan Nissenbaum

4
มีความคิดเกี่ยวกับการใช้งาน CPU หรือไม่
Mihir Mehta

@Michael Taylor นี้เป็นสิ่งที่ดีขอบคุณ แต่คำถามเกี่ยวกับ RAM ที่ใช้ในปัจจุบันสำหรับ OS X ปรากฏว่าคุณได้รับสถิติ VM ไม่ใช่หน่วยความจำกายภาพ อันที่จริงกรณีนี้หรือไม่
Edgar Aroutiounian

1
เราจะคำนวณหน่วยความจำแอพและแคชหน่วยความจำเช่นการตรวจสอบกิจกรรมได้อย่างไร ฉันใช้ vm_stats.inactive_page_count * page_size t คำนวณ FIle Cache แต่ไม่ได้ซิงโครไนซ์กับการตรวจสอบกิจกรรม ขอบคุณล่วงหน้า
Amit Khandelwal

1
ผู้เขียนดั้งเดิมดูเหมือนจะสับสนเกี่ยวกับ "หน่วยความจำเสมือน" - ในบางบริบทมันไม่ได้อ้างถึงหน่วยความจำแบบสลับไปยังดิสก์ แต่เป็นพื้นที่ที่อยู่เสมือนจริง ค้นหาระบบที่ไม่ได้ใช้การสลับใด ๆ และคุณจะเห็นว่ากระบวนการส่วนใหญ่มีขนาด "คุณธรรม" มากกว่าขนาด "rss" ในส่วน "หน่วยความจำเสมือนที่กระบวนการของฉันใช้อยู่ในปัจจุบัน" นั่นคือสิ่งที่ "หน่วยความจำเสมือน" อ้างถึง - พื้นที่ที่อยู่ไม่ใช่หน่วยความจำแบบสลับเป็นดิสก์
Pierce

63

ลินุกซ์

ใน 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 โดยรวมมีอยู่ตั้งแต่เริ่มต้นระบบ นี่อาจไม่ใช่สิ่งที่คุณสนใจหากคุณต้องการทราบว่าการใช้งาน CPU ในช่วงวินาทีสุดท้ายหรือ 10 วินาทีจากนั้นคุณต้องค้นหาข้อมูลและคำนวณด้วยตัวคุณเอง

ข้อมูลมีอยู่ใน/ proc / statซึ่งจัดทำเป็นเอกสารค่อนข้างดีที่http://www.linuxhowtos.org/System/procstat.htm ; นี่คือสิ่งที่ดูเหมือนในกล่อง 4-core ของฉัน:

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 และเพิ่มขึ้น อย่านับบรรทัด 'cpu' ซึ่งเป็นการรวมกันของบรรทัด cpuN ในตัวอย่างของฉันคุณสามารถเห็น cpu0 ถึง cpu3 สำหรับโปรเซสเซอร์ 4 ตัว จากนี้ไปคุณสามารถละเว้น cpu0..cpu3 และเน้นเฉพาะที่บรรทัด 'cpu'

ถัดไปคุณต้องรู้ว่าตัวเลขที่สี่ในบรรทัดเหล่านี้เป็นการวัดเวลาว่างดังนั้นตัวเลขที่สี่ในบรรทัด 'cpu' จึงเป็นเวลาว่างทั้งหมดสำหรับตัวประมวลผลทั้งหมดตั้งแต่เวลาบูต เวลานี้วัดใน Linux "jiffies" ซึ่งมีค่า 1/100 วินาทีต่อวินาที

แต่คุณไม่สนใจเวลาว่างทั้งหมด คุณสนใจเวลาว่างในช่วงเวลาที่กำหนดเช่นวินาทีสุดท้าย ทำการคำนวณว่าคุณต้องอ่านไฟล์นี้สองครั้งห่างกัน 1 วินาทีจากนั้นคุณสามารถทำผลต่างของค่าที่สี่ของบรรทัด ตัวอย่างเช่นถ้าคุณนำตัวอย่างและรับ:

cpu  2330047 0 2365006 1063853632 9035 9463 96114 0

จากนั้นหนึ่งวินาทีต่อมาคุณจะได้รับตัวอย่างนี้:

cpu  2330047 0 2365007 1063854028 9035 9463 96114 0

ลบตัวเลขทั้งสองออกและคุณจะได้ผลต่างเท่ากับ 396 ซึ่งหมายความว่า CPU ของคุณไม่มีการใช้งานเป็นเวลา 3.96 วินาทีจากช่วง 1.00 วินาทีสุดท้าย แน่นอนว่าเคล็ดลับคือคุณต้องหารด้วยจำนวนโปรเซสเซอร์ 3.96 / 4 = 0.99 และมีเปอร์เซ็นต์ว่างของคุณ ว่าง 99% และไม่ว่าง 1%

ในรหัสของฉันฉันมีริงบัฟเฟอร์ 360 รายการและฉันอ่านไฟล์นี้ทุกวินาที นั่นทำให้ฉันคำนวณการใช้งาน CPU ได้อย่างรวดเร็วเป็นเวลา 1 วินาที 10 วินาที ฯลฯ ไปจนถึง 1 ชั่วโมง

สำหรับข้อมูลเฉพาะกระบวนการคุณต้องดูใน/ proc / pid ; หากคุณไม่สนใจ abid pid ของคุณคุณสามารถดู / proc / self

CPU ที่ใช้โดยกระบวนการของคุณสามารถใช้ได้ใน/ proc / ตนเอง / สถิติ ไฟล์นี้เป็นไฟล์ที่มีลักษณะแปลกประกอบด้วยหนึ่งบรรทัด ตัวอย่างเช่น:

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 คือจำนวนของระยะเวลาอันสั้นที่กระบวนการดำเนินการในโหมดผู้ใช้และลำดับที่ 14 คือจำนวนระยะเวลาอันสั้นที่กระบวนการดำเนินการในโหมดเคอร์เนล เพิ่มทั้งสองเข้าด้วยกันและคุณมีการใช้งาน CPU ทั้งหมด

อีกครั้งคุณจะต้องทดลองใช้ไฟล์นี้เป็นระยะและคำนวณส่วนต่างเพื่อพิจารณาการใช้งาน CPU ของกระบวนการในช่วงเวลาหนึ่ง

แก้ไข: จำไว้ว่าเมื่อคุณคำนวณการใช้ CPU ของกระบวนการคุณต้องคำนึงถึง 1) จำนวนเธรดในกระบวนการของคุณและ 2) จำนวนตัวประมวลผลในระบบ ตัวอย่างเช่นหากกระบวนการเธรดเดี่ยวของคุณใช้ CPU เพียง 25% นั่นอาจจะดีหรือไม่ดีก็ได้ ดีในระบบตัวประมวลผลเดียว แต่ไม่ดีในระบบตัวประมวลผล 4 ตัว ซึ่งหมายความว่ากระบวนการของคุณทำงานอย่างต่อเนื่องและใช้ 100% ของรอบ CPU ที่มีให้

สำหรับข้อมูลหน่วยความจำเฉพาะกระบวนการคุณต้องดู / 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,296 kB หรือประมาณ 410 เมกะไบต์) ความแตกต่าง: โปรแกรมของฉันมีการแมป 636 MB ผ่าน mmap () แต่มีการเข้าถึงเพียง 410 MB เท่านั้นดังนั้นจึงมีการกำหนดหน้าเว็บให้เพียง 410 MB เท่านั้น

รายการเดียวที่ผมไม่แน่ใจว่าเกี่ยวกับการSwapspace ปัจจุบันที่ใช้โดยกระบวนการของฉัน ฉันไม่ทราบว่าสิ่งนี้สามารถใช้ได้


1
ขอบคุณ Martin ถ้าฉันมีข้อมูลทั้งหมดที่รวบรวมไว้ในที่แห่งเดียวมันจะช่วยให้ฉันพักสักสองสามคืน ... BTW: Swapspace ของกระบวนการปัจจุบัน = VmSize - VmRSS ใช่ไหม?
Lanzelot

14

ใน 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;
    }

สิ่งนี้สามารถแก้ไขได้สำหรับฟังก์ชั่น DLL ภายนอกที่ฉันสามารถโทรหาใน c # ได้ในภายหลัง?
นิโก้

11
การจัดรูปแบบของusage =เป็นสิ่งที่สร้างสรรค์ที่สุดที่ฉันเคยเห็นในขณะที่ไม่สามารถอ่านได้ทั้งหมด แต่สร้างสรรค์
ViRuSTriNiTy

คำเตือน: การแสดงออกในรหัสข้างต้นที่คำนวณ 'การใช้งาน' เป็นวิธีการออก หากระบบไม่ได้ใช้งานระบบจะหารด้วยศูนย์ ในกรณีที่เวลาว่างเท่ากับเวลาของผู้ใช้ + เคอร์เนลก็จะสร้าง 0 มากกว่า 50% ตามที่คาดไว้
Andrei Belogortseff

โปรดจำไว้ว่าตาม MSDN ปัจจุบันเวลาเคอร์เนลจะรวมเวลาว่างด้วย!
Andrei Belogortseff

@sayyedmohsenzahraee: ฉันยังไม่ได้ตรวจสอบตรรกะของมันเพียงแค่ความคิดเห็นเกี่ยวกับรหัสตัวเอง 1) ใช้ตัวแปร 64 บิตธรรมดาแทนสหภาพคือULONGLONGสำหรับ VS ULARGE_INTEGERแทน 2) คุณกำลังพูดถึงเรื่องโทรศัพท์CopyMemory()มากเกินไปULONGLONG ul_sys_idle = *(ULONGLONG*)&ft_sys_idle;แทน มันจะถูกแปลเป็นคำสั่งCPU mov(หรือlea) เดียว
ahmd0

12

ลินุกซ์

วิธีพกพาในการอ่านหน่วยความจำและหมายเลขโหลดคือการ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.

3

QNX

เนื่องจากนี่เป็นเหมือน "wikipage of code" ฉันต้องการเพิ่มรหัสบางอย่างจากฐานความรู้ 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;
} 

1

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;
}

0

สำหรับ Linux คุณยังสามารถใช้ / proc / self / statm เพื่อรับตัวเลขบรรทัดเดียวที่มีข้อมูลหน่วยความจำกระบวนการที่สำคัญซึ่งเป็นสิ่งที่เร็วกว่าในการประมวลผลมากกว่าที่จะผ่านรายการข้อมูลที่รายงานจำนวนมากเมื่อคุณได้รับจาก proc / self / status

ดู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)

1
ใครรู้ว่าขนาดรวมที่รายงานในหน้านั้นเชื่อถือได้แค่ไหน รอยเท้านี้เป็นจริงในหน่วยความจำในหน้า?
niken

-1

ฉันใช้รหัสต่อไปนี้ในโครงการ 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);

คุณไม่ได้รับค่าเช่น 0.00% และค่าเกินกว่า 100% โดยกลไกนี้หรือไม่?
Buddhika Chaturanga

นี่สำหรับ Mac OS หรือไม่
RuLoViC

@RuLoViC สำหรับ Windows
ไม่ใช่รูปสี่เหลี่ยม
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.