How to find out how much memory my C ++ application on Mac uses

Some operations in my application use more memory than I think, and I would like to record the current memory usage to determine what they are.

Is there a system call that will return the amount of memory used?

+3
source share
4 answers

The following C function returns the CPU time and the resident memory of the pid process. To get the resources of other processes, you need to get root permission. You can also try getrusage (), but I never get it properly for in-memory use. Getting CPU time with getrusage () always works with me.

ps top. , .

#ifdef __APPLE__

#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/vmmeter.h>
#include <mach/mach_init.h>
#include <mach/mach_host.h>
#include <mach/mach_port.h>
#include <mach/mach_traps.h>
#include <mach/task_info.h>
#include <mach/thread_info.h>
#include <mach/thread_act.h>
#include <mach/vm_region.h>
#include <mach/vm_map.h>
#include <mach/task.h>
#include <mach/shared_memory_server.h>

typedef struct vmtotal vmtotal_t;

typedef struct { /* dynamic process information */
    size_t rss, vsize;
    double utime, stime;
} RunProcDyn;

/* On Mac OS X, the only way to get enough information is to become root. Pretty frustrating!*/
int run_get_dynamic_proc_info(pid_t pid, RunProcDyn *rpd)
{
    task_t task;
    kern_return_t error;
    mach_msg_type_number_t count;
    thread_array_t thread_table;
    thread_basic_info_t thi;
    thread_basic_info_data_t thi_data;
    unsigned table_size;
    struct task_basic_info ti;

    error = task_for_pid(mach_task_self(), pid, &task);
    if (error != KERN_SUCCESS) {
        /* fprintf(stderr, "++ Probably you have to set suid or become root.\n"); */
        rpd->rss = rpd->vsize = 0;
        rpd->utime = rpd->stime = 0;
        return 0;
    }
    count = TASK_BASIC_INFO_COUNT;
    error = task_info(task, TASK_BASIC_INFO, (task_info_t)&ti, &count);
    assert(error == KERN_SUCCESS);
    { /* adapted from ps/tasks.c */
        vm_region_basic_info_data_64_t b_info;
        vm_address_t address = GLOBAL_SHARED_TEXT_SEGMENT;
        vm_size_t size;
        mach_port_t object_name;
        count = VM_REGION_BASIC_INFO_COUNT_64;
        error = vm_region_64(task, &address, &size, VM_REGION_BASIC_INFO,
                             (vm_region_info_t)&b_info, &count, &object_name);
        if (error == KERN_SUCCESS) {
            if (b_info.reserved && size == (SHARED_TEXT_REGION_SIZE) &&
                ti.virtual_size > (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE))
            {
                ti.virtual_size -= (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE);
            }
        }
        rpd->rss = ti.resident_size;
        rpd->vsize = ti.virtual_size;
    }
    { /* calculate CPU times, adapted from top/libtop.c */
        unsigned i;
        rpd->utime = ti.user_time.seconds + ti.user_time.microseconds * 1e-6;
        rpd->stime = ti.system_time.seconds + ti.system_time.microseconds * 1e-6;
        error = task_threads(task, &thread_table, &table_size);
        assert(error == KERN_SUCCESS);
        thi = &thi_data;
        for (i = 0; i != table_size; ++i) {
            count = THREAD_BASIC_INFO_COUNT;
            error = thread_info(thread_table[i], THREAD_BASIC_INFO, (thread_info_t)thi, &count);
            assert(error == KERN_SUCCESS);
            if ((thi->flags & TH_FLAGS_IDLE) == 0) {
                rpd->utime += thi->user_time.seconds + thi->user_time.microseconds * 1e-6;
                rpd->stime += thi->system_time.seconds + thi->system_time.microseconds * 1e-6;
            }
            if (task != mach_task_self()) {
                error = mach_port_deallocate(mach_task_self(), thread_table[i]);
                assert(error == KERN_SUCCESS);
            }
        }
        error = vm_deallocate(mach_task_self(), (vm_offset_t)thread_table, table_size * sizeof(thread_array_t));
        assert(error == KERN_SUCCESS);
    }
    mach_port_deallocate(mach_task_self(), task);
    return 0;
}

#endif /* __APPLE__ */
+8

. ...

+2

@user172818, getrusage, :

#include <sys/time.h>
#include <sys/resource.h>

long getMemoryUsage() 
{
  struct rusage usage;
  if(0 == getrusage(RUSAGE_SELF, &usage))
    return usage.ru_maxrss; // bytes
  else
    return 0;
}

Mac OS X 10.9.4, Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn).

0

All Articles