A way to determine a process's “real” memory u

2019-01-07 02:29发布

Tools like 'ps' and 'top' report various kinds of memory usages, such as the VM size and the Resident Set Size. However, none of those are the "real" memory usage:

  • Program code is shared between multiple instances of the same program.
  • Shared library program code is shared between all processes that use that library.
  • Some apps fork off processes and share memory with them (e.g. via shared memory segments).
  • The virtual memory system makes the VM size report pretty much useless.
  • RSS is 0 when a process is swapped out, making it not very useful.
  • Etc etc.

I've found that the private dirty RSS, as reported by Linux, is the closest thing to the "real" memory usage. This can be obtained by summing all Private_Dirty values in /proc/somepid/smaps.

However, do other operating systems provide similar functionality? If not, what are the alternatives? In particular, I'm interested in FreeBSD and OS X.

10条回答
够拽才男人
2楼-- · 2019-01-07 02:53

You really can't.

I mean, shared memory between processes... are you going to count it, or not. If you don't count it, you are wrong; the sum of all processes' memory usage is not going to be the total memory usage. If you count it, you are going to count it twice- the sum's not going to be correct.

Me, I'm happy with RSS. And knowing you can't really rely on it completely...

查看更多
甜甜的少女心
3楼-- · 2019-01-07 03:01

On Linux, you may want the PSS (proportional set size) numbers in /proc/self/smaps. A mapping's PSS is its RSS divided by the number of processes which are using that mapping.

查看更多
▲ chillily
4楼-- · 2019-01-07 03:04

Check it out, this is the source code of gnome-system-monitor, it thinks the memory "really used" by one process is sum(info->mem) of X Server Memory(info->memxserver) and Writable Memory(info->memwritable), the "Writable Memory" is the memory blocks which are marked as "Private_Dirty" in /proc/PID/smaps file.

Other than linux system, could be different way according to gnome-system-monitor code.

static void
get_process_memory_writable (ProcInfo *info)
{
    glibtop_proc_map buf;
    glibtop_map_entry *maps;

    maps = glibtop_get_proc_map(&buf, info->pid);

    gulong memwritable = 0;
    const unsigned number = buf.number;

    for (unsigned i = 0; i < number; ++i) {
#ifdef __linux__
        memwritable += maps[i].private_dirty;
#else
        if (maps[i].perm & GLIBTOP_MAP_PERM_WRITE)
            memwritable += maps[i].size;
#endif
    }

    info->memwritable = memwritable;

    g_free(maps);
}

static void
get_process_memory_info (ProcInfo *info)
{
    glibtop_proc_mem procmem;
    WnckResourceUsage xresources;

    wnck_pid_read_resource_usage (gdk_screen_get_display (gdk_screen_get_default ()),
                                  info->pid,
                                  &xresources);

    glibtop_get_proc_mem(&procmem, info->pid);

    info->vmsize    = procmem.vsize;
    info->memres    = procmem.resident;
    info->memshared = procmem.share;

    info->memxserver = xresources.total_bytes_estimate;

    get_process_memory_writable(info);

    // fake the smart memory column if writable is not available
    info->mem = info->memxserver + (info->memwritable ? info->memwritable : info->memres);
}
查看更多
Root(大扎)
5楼-- · 2019-01-07 03:08

You can get private dirty and private clean RSS from /proc/pid/smaps

查看更多
Emotional °昔
6楼-- · 2019-01-07 03:09

For a question that mentioned Freebsd, surprised no one wrote this yet :

If you want a linux style /proc/PROCESSID/status output, please do the following :

mount -t linprocfs none /proc
cat /proc/PROCESSID/status

Atleast in FreeBSD 7.0, the mounting was not done by default ( 7.0 is a much older release,but for something this basic,the answer was hidden in a mailing list!)

查看更多
姐就是有狂的资本
7楼-- · 2019-01-07 03:11
for i in /proc/[0-9]*; do
  grep -q 'Private_Dirty' $i/smaps;
  if [ $? -ne 0 ]; then
    continue;
  fi;
  echo -n "${i}: ";
  awk '/Private_Dirty/ {print $2,$3}' $i/smaps |
   sed 's/ tB/*1024 gB/;s/ gB/*1024 mB/;s/ mB/*1024 kB/;s/ kB/*1024/;1!s/^/+/;' |
   tr -d '\n' |
   sed 's/$/\n/' |
   bc |
   tr -d '\n';
  echo;
done |
 sort -n -k 2
查看更多
登录 后发表回答