A way to determine a process's “real” memory usage, i.e. private dirty RSS?

后端 未结 10 1642
我在风中等你
我在风中等你 2020-11-29 15:15

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:

相关标签:
10条回答
  • 2020-11-29 16:11

    Take a look at smem. It will give you PSS information

    http://www.selenic.com/smem/

    0 讨论(0)
  • 2020-11-29 16:12

    Use the mincore(2) system call. Quoting the man page:

    DESCRIPTION
         The mincore() system call determines whether each of the pages in the
         region beginning at addr and continuing for len bytes is resident.  The
         status is returned in the vec array, one character per page.  Each
         character is either 0 if the page is not resident, or a combination of
         the following flags (defined in <sys/mman.h>):
    
    0 讨论(0)
  • 2020-11-29 16:14

    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);
    }
    
    0 讨论(0)
  • 2020-11-29 16:15

    Reworked this to be much cleaner, to demonstrate some proper best practices in bash, and in particular to use awk instead of bc.

    find /proc/ -maxdepth 1 -name '[0-9]*' -print0 | while read -r -d $'\0' pidpath; do
      [ -f "${pidpath}/smaps" ] || continue
      awk '!/^Private_Dirty:/ {next;}
           $3=="kB" {pd += $2 * (1024^1); next}
           $3=="mB" {pd += $2 * (1024^2); next}
           $3=="gB" {pd += $2 * (1024^3); next}
           $3=="tB" {pd += $2 * (1024^4); next}
           $3=="pB" {pd += $2 * (1024^5); next}
           {print "ERROR!!  "$0 >"/dev/stderr"; exit(1)}
           END {printf("%10d: %d\n", '"${pidpath##*/}"', pd)}' "${pidpath}/smaps" || break
    done
    

    On a handy little container on my machine, with | sort -n -k 2 to sort the output, this looks like:

            56: 106496
             1: 147456
            55: 155648
    
    0 讨论(0)
提交回复
热议问题