How to determine CPU and memory consumption from inside a process?

后端 未结 9 1701
被撕碎了的回忆
被撕碎了的回忆 2020-11-21 11:28

I once had the task of determining the following performance parameters from inside a running application:

  • Total virtual memory available
  • Virtual memo
9条回答
  •  春和景丽
    2020-11-21 12:30

    Mac OS X

    I was hoping to find similar information for Mac OS X as well. Since it wasn't here, I went out and dug it up myself. Here are some of the things I found. If anyone has any other suggestions, I'd love to hear them.

    Total Virtual Memory

    This one is tricky on Mac OS X because it doesn't use a preset swap partition or file like Linux. Here's an entry from Apple's documentation:

    Note: Unlike most Unix-based operating systems, Mac OS X does not use a preallocated swap partition for virtual memory. Instead, it uses all of the available space on the machine’s boot partition.

    So, if you want to know how much virtual memory is still available, you need to get the size of the root partition. You can do that like this:

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

    Total Virtual Currently Used

    Calling systcl with the "vm.swapusage" key provides interesting information about swap usage:

    sysctl -n vm.swapusage
    vm.swapusage: total = 3072.00M  used = 2511.78M  free = 560.22M  (encrypted)
    

    Not that the total swap usage displayed here can change if more swap is needed as explained in the section above. So the total is actually the current swap total. In C++, this data can be queried this way:

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

    Note that the "xsw_usage", declared in sysctl.h, seems not documented and I suspect there there is a more portable way of accessing these values.

    Virtual Memory Currently Used by my Process

    You can get statistics about your current process using the task_info function. That includes the current resident size of your process and the current virtual size.

    #include
    
    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;
    

    Total RAM available

    The amount of physical RAM available in your system is available using the sysctl system function like this:

    #include 
    #include 
    ...
    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 Currently Used

    You can get general memory statistics from the host_statistics system function.

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

    One thing to note here are that there are five types of memory pages in Mac OS X. They are as follows:

    1. Wired pages that are locked in place and cannot be swapped out
    2. Active pages that are loading into physical memory and would be relatively difficult to swap out
    3. Inactive pages that are loaded into memory, but haven't been used recently and may not even be needed at all. These are potential candidates for swapping. This memory would probably need to be flushed.
    4. Cached pages that have been some how cached that are likely to be easily reused. Cached memory probably would not require flushing. It is still possible for cached pages to be reactivated
    5. Free pages that are completely free and ready to be used.

    It is good to note that just because Mac OS X may show very little actual free memory at times that it may not be a good indication of how much is ready to be used on short notice.

    RAM Currently Used by my Process

    See the "Virtual Memory Currently Used by my Process" above. The same code applies.

提交回复
热议问题