如何获得进程的准确共享内存大小?

010*_*tes 6 linux memory-management shared-memory

我试图在Linux上获得进程的共享内存大小.这是使用2个不同命令的结果:

  1. 顶部并检查SHR字段:

     PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
    1734 root      20   0  201m 4072 1012 S  0.0  0.1  22:00.65 php-fpm
    
    Run Code Online (Sandbox Code Playgroud)
  2. pmap -d:

    mapped: 206672K    writeable/private: 4352K    shared: 128K
    
    Run Code Online (Sandbox Code Playgroud)

您可以看到pmap中的共享内存大小远小于top.

我读了一些源代码来找到原因.top似乎从/ proc // statm读取值,值由以下公式计算:

unsigned long task_statm(struct mm_struct *mm,
    unsigned long *shared, unsigned long *text,
    unsigned long *data, unsigned long *resident)
{
    *shared = get_mm_counter(mm, MM_FILEPAGES);
    *text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK))
                                                       >> PAGE_SHIFT;
    *data = mm->total_vm - mm->shared_vm;
    *resident = *shared + get_mm_counter(mm, MM_ANONPAGES);
    return mm->total_vm;
}
Run Code Online (Sandbox Code Playgroud)

似乎所有文件页都被视为共享内存?

pmap命令从/ proc // maps读取信息,然后通过一些标志计算共享内存:

3dc822a000-3dc822d000 rw-p 0002a000 08:13 5134288      /usr/lib64/libmcrypt.so.4.4.8
start-end flags file_offset dev_major:dev_minor inode
Run Code Online (Sandbox Code Playgroud)

如果flags [3] =='s',则此地图将被计为共享地图.

所以我的问题是哪一个更准确?为什么他们有不同的方法来计算共享内存大小?

提前致谢!

twa*_*erg 2

SHR中的列所报告的内容与s条目所top报告的内容不同。正在报告与其他进程共享的内存量,因为它位于一次加载到内存中的动态库中,并且使用该库的所有进程在其映像中都包含相同的页面,因为这些页面是只读的。似乎显示“共享内存”段,这些段是可以读写或只读的数据页,并且在具有和 相关功能的进程之间共享。pmapsharedtoppmapshmget()