内存优化
目录
1 工具选择
- pmap
- gdb
- perf
- valgrind
- /proc 文件系统
1.1 pmap工具
- 查看支持的选项
(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] 显示详细的内存映射
- 查询内存占用
(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) 地址
0000000000400000到00000000039a5000- ①程序的代码段(.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)地址
00007ffff6c8f000到00007ffff6e96000表示动态库加载到内存中映射的地址,其中00007ffff6c96000区域标记为---p表示它是"不可读、不可写、不可执行"的。这通常是动态库文件的一个空白区域,用于内存的保护或者对齐。3)地址
00007ffff7fd4000到ffffffffff600000- anon: 匿名内存区域,通常用于动态分配的堆或其他不与文件直接关联的内存。
- vvar: 虚拟变量区域,用于内核和用户空间共享一些动态数据,如时钟信息。
- vdso: 虚拟动态共享对象,用于提供一些内核功能的用户空间接口,比如获取系统时间的优化函数。
- stack: 进程的栈区域,用于存储局部变量和函数调用信息。
- vsyscall: 虚拟系统调用区域,旧版本的Linux用来实现系统调用的快速路径,现在大多被替代为vdso。
-
参数解析
- SIZE:
- 定义: 映射区域的总大小。
- 含义: 内存映射区域的总内存占用,包括所有的虚拟内存区域。
- RSS (Resident Set Size):
- 定义: 实际驻留在物理内存中的大小。
- 含义: 实际使用的物理内存量,排除被交换到磁盘的部分。
- PSS (Proportional Set Size):
- 定义: 进程实际使用的物理内存的一个更精确的度量。
- 含义: PSS 试图解决多进程共享内存的情况,通过将共享内存的大小按比例分配给每个进程,提供一个更准确的每个进程内存占用的估算。它比 RSS 更能反映进程独占的物理内存。
- DIRTY:
- 定义: 已修改但尚未写回到磁盘的内存页面的大小。
- 含义: 表示内存中已经被修改的页面的总大小,这些页面在将来可能需要写回磁盘。这个度量反映了进程对内存的修改情况,以及可能需要的额外磁盘 I/O 操作。
- Shared:
- 定义: 共享内存的大小。
- 含义: 多个进程共享的区域。例如,动态链接库(共享库)通常被多个进程共享。
- Referenced:
- 定义: 被引用的内存的大小。
- 含义: 被当前进程或系统引用的内存,包括实际被访问过的部分。referenced 指的是当前处于使用状态的内存页,无论这些页是物理内存中的还是被换出的。这个指标反映了内存的活跃程度。
- SIZE:
1.2 /proc文件系统
- /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 # 线程数量
- /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获得更详细的信息。