目录

内存优化

  1. pmap
  2. gdb
  3. perf
  4. valgrind
  5. /proc 文件系统
  1. 查看支持的选项
(base) kwephispre11269:~ # pmap --help
usage: pmap [options] pid [...]
  -d, --device         display offset and device numbers
  -q, --quiet          hide header and memory statistics
  -A, --limit=low,high limit results to the given range
  -V, --version        display version information
  -h, --help           display this help

不同版本或许支持更多选项,例如 pmap -r [pid] 仅显示只读内存映射 pmap -x [pid] 显示详细的内存映射

  1. 查询内存占用
(base) kwephispre11269:~ # pmap 30765
30765: tdpdk
START               SIZE     RSS     PSS   DIRTY PERM MAPPING
0000000000400000  52764K   8832K   8764K     36K r-xp /data/tdpdk
0000000003987000    120K    120K    120K      8K r--p /data/tdpdk
00000000039a5000    380K    216K    216K    116K rw-p /data/tdpdk
0000000003a04000   5428K   1204K   1204K   1204K rw-p [heap]
0000000100000000     28K     28K     28K      0K rw-s /opt/data/dpdk/rte/config
0000000100007000    184K    184K    184K      0K rw-s /opt/data/dpdk/rte/fbarray_memzone
0000000100035000    388K    388K    388K      0K rw-s /opt/data/dpdk/rte/fbarray_memseg-2048k-0-0
0000000100200000   2048K      0K      0K      0K rw-s /mnt/hugepages/rtemap_0
0000000100400000   2048K      0K      0K      0K rw-s /mnt/hugepages/rtemap_1
...
0000000113000000   2048K      0K      0K      0K rw-s /mnt/hugepages/rtemap_151
0000000113200000 16465920K      0K      0K      0K ---p [anon]
0000000500200000    388K    388K    388K      0K rw-s /opt/data/dpdk/rte/fbarray_memseg-2048k-0-1
...
00007ffff648f000   8192K     16K     16K     16K rw-p [anon]
00007ffff6c8f000     28K     28K      0K      0K r-xp /lib64/librt-2.31.so
00007ffff6c96000   2044K      0K      0K      0K ---p /lib64/librt-2.31.so
00007ffff6e95000      4K      4K      4K      4K r--p /lib64/librt-2.31.so
00007ffff6e96000      4K      4K      4K      4K rw-p /lib64/librt-2.31.so
00007ffff6e97000   1736K   1572K     48K      4K r-xp /lib64/libc-2.31.so
00007ffff7049000   2048K      0K      0K      0K ---p /lib64/libc-2.31.so
00007ffff7249000     16K     16K     16K     16K r--p /lib64/libc-2.31.so
00007ffff724d000      8K      8K      8K      8K rw-p /lib64/libc-2.31.so
...
00007ffff7fd4000     32K     28K     28K     28K rw-p [anon]
00007ffff7ff7000     12K      0K      0K      0K r--p [vvar]
00007ffff7ffa000      8K      8K      2K      0K r-xp [vdso]
00007ffff7ffc000      4K      4K      4K      4K r--p /lib64/ld-2.31.so
00007ffff7ffd000      8K      8K      8K      8K rw-p /lib64/ld-2.31.so
00007ffffffde000    132K     32K     32K     32K rw-p [stack]
ffffffffff600000      4K      0K      0K      0K r-xp [vsyscall]
Total:           68391664K  15060K  12852K   2044K
163804K writable-private, 67914800K readonly-private, 313060K shared, and 15044K referenced
  1. 内存解析

    1) 地址000000000040000000000000039a5000

    • ①程序的代码段(.text segment): 映射区域: 0000000000400000 到 0000000003987000 权限: r-xp 说明: 这是程序的可执行代码部分。代码段(.text segment)包含了程序的指令集,程序在运行时,这一部分的内容不会被修改。
    • ② 只读数据段(.rodata segment): 映射区域: 0000000003987000 到 00000000039a5000 权限: r–p 说明: 这是程序的只读数据部分,通常包含了常量和只读数据。这部分数据在程序运行时不应该被修改,因此具有只读权限。
    • ③ 可读写数据段(.data segment 和 .bss segment): 映射区域: 00000000039a5000 到 0000000003a04000 权限: rw-p 说明: 这是程序的读写数据部分。包括了初始化的数据(.data segment)和未初始化的数据(.bss segment)。这些区域允许读写操作。 - .data segment: 包含了程序中已初始化的全局变量和静态变量。它们可以在程序运行时被修改。 - .bss segment: 包含了未初始化的全局变量和静态变量。在程序开始时,这些变量被初始化为零或空值。虽然在内存中是可写的,但其初始值是由操作系统在加载程序时设置的。

    2)地址00007ffff6c8f00000007ffff6e96000 表示动态库加载到内存中映射的地址,其中00007ffff6c96000区域标记为 ---p 表示它是"不可读、不可写、不可执行"的。这通常是动态库文件的一个空白区域,用于内存的保护或者对齐。

    3)地址00007ffff7fd4000ffffffffff600000

    • anon: 匿名内存区域,通常用于动态分配的堆或其他不与文件直接关联的内存。
    • vvar: 虚拟变量区域,用于内核和用户空间共享一些动态数据,如时钟信息。
    • vdso: 虚拟动态共享对象,用于提供一些内核功能的用户空间接口,比如获取系统时间的优化函数。
    • stack: 进程的栈区域,用于存储局部变量和函数调用信息。
    • vsyscall: 虚拟系统调用区域,旧版本的Linux用来实现系统调用的快速路径,现在大多被替代为vdso。
  2. 参数解析

    • SIZE:
      • 定义: 映射区域的总大小。
      • 含义: 内存映射区域的总内存占用,包括所有的虚拟内存区域。
    • RSS (Resident Set Size):
      • 定义: 实际驻留在物理内存中的大小。
      • 含义: 实际使用的物理内存量,排除被交换到磁盘的部分。
    • PSS (Proportional Set Size):
      • 定义: 进程实际使用的物理内存的一个更精确的度量。
      • 含义: PSS 试图解决多进程共享内存的情况,通过将共享内存的大小按比例分配给每个进程,提供一个更准确的每个进程内存占用的估算。它比 RSS 更能反映进程独占的物理内存。
    • DIRTY:
      • 定义: 已修改但尚未写回到磁盘的内存页面的大小。
      • 含义: 表示内存中已经被修改的页面的总大小,这些页面在将来可能需要写回磁盘。这个度量反映了进程对内存的修改情况,以及可能需要的额外磁盘 I/O 操作。
    • Shared:
      • 定义: 共享内存的大小。
      • 含义: 多个进程共享的区域。例如,动态链接库(共享库)通常被多个进程共享。
    • Referenced:
      • 定义: 被引用的内存的大小。
      • 含义: 被当前进程或系统引用的内存,包括实际被访问过的部分。referenced 指的是当前处于使用状态的内存页,无论这些页是物理内存中的还是被换出的。这个指标反映了内存的活跃程度。
  1. /proc/pid/status
(base) kwephispre11269:/proc/30765 # cat status
Name:   tdpdk
...
VmPeak: 68457196 kB                    # 进程在其生命周期中占用的最大虚拟内存
VmSize: 68391660 kB                    # 进程当前的虚拟内存使用量
VmLck:         0 kB                    # 被锁定的内存大小,通常用于实时任务
VmPin:         0 kB                    # 被系统标记为不会被交换到磁盘的内存大小
VmHWM:     14524 kB                    # 进程生命周期中使用的最大实际物理内存(即RSS)
VmRSS:     14524 kB                    # 进程实际占用的物理内存,不包括交换出去的部分
RssAnon:            1668 kB            # 进程的匿名映射(未映射到文件的内存区域)占用的物理内存量
RssFile:           12856 kB            # 进程的文件映射区域(如共享库或文件映射到内存中的部分)占用的物理内存量
RssShmem:              0 kB            # 共享内存区域占用的物理内存量
VmData:   163672 kB                    # 数据段虚拟内存大小
VmStk:       132 kB                    # 栈段虚拟内存大小
VmExe:     52764 kB                    # 执行文件(即程序代码)的虚拟内存大小
VmLib:      3432 kB                    # 共享库的虚拟内存大小
VmPTE:       268 kB                    # 存储页面表项的虚拟内存大小
VmPMD:        28 kB                    # 存储页目录项的虚拟内存大小
VmSwap:        0 kB                    # 交换空间的虚拟内存大小
HugetlbPages:     311296 kB            # 大页内存(Huge Pages)使用的大小
Threads:        20                     # 线程数量
  1. /proc/pid/maps
(base) kwephispre11269:/proc/30765 # cat maps
00400000-03787000 r-xp 00000000 fe:00 7782973                            /data/tdpdk
03987000-039a5000 r--p 03387000 fe:00 7782973                            /data/tdpdk
039a5000-03a04000 rw-p 033a5000 fe:00 7782973                            /data/tdpdk
03a04000-03f51000 rw-p 00000000 00:00 0                                  [heap]
100000000-100007000 rw-s 00000000 fd:01 1573825                          /opt/data/dpdk/rte/config
100007000-100035000 rw-s 00000000 fd:01 1573833                          /opt/data/dpdk/rte/fbarray_memzone
100035000-100096000 rw-s 00000000 fd:01 1573834                          /opt/data/dpdk/rte/fbarray_memseg-2048k-0-0
100200000-100400000 rw-s 00000000 00:34 170393186                        /mnt/hugepages/rtemap_0
100400000-100600000 rw-s 00000000 00:34 170393481                        /mnt/hugepages/rtemap_1
...
7ffff7dd4000-7ffff7dfc000 r-xp 00000000 fd:01 1966331                    /lib64/ld-2.31.so
7ffff7fd4000-7ffff7fdc000 rw-p 00000000 00:00 0
7ffff7ff7000-7ffff7ffa000 r--p 00000000 00:00 0                          [vvar]
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0                          [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00028000 fd:01 1966331                    /lib64/ld-2.31.so
7ffff7ffd000-7ffff7fff000 rw-p 00029000 fd:01 1966331                    /lib64/ld-2.31.so
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0                          [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

查看该文件同pmap工具查询一致,可以查询smaps获得更详细的信息。