嵌入式设备内存分析

前些时间在工作中遇到设备上某个进行占用虚拟内存过大,需要对其进行分析定位。而进程中使用虚拟内存最多的地方主要有malloc申请未释放,定义全局量使用,链接开源库。

下面以xx_event_agent进程进行分析,首先ps查看该进程id为280。

/proc/pid/status

root@WDFG201-D:/proc/280 # cat status

Name: xx_event_agent

Umask: 0022

State: S (sleeping)

Tgid: 280

Ngid: 0

Pid: 280

PPid: 1

TracerPid: 0

Uid: 0 0 0 0

Gid: 0 0 0 0

FDSize: 32

Groups:  

VmPeak:    58688 kB

VmSize:    58652 kB

VmLck:        0 kB

VmPin:        0 kB

VmHWM:     2892 kB

VmRSS:     2888 kB

RssAnon:      252 kB

RssFile:     2544 kB

RssShmem:       92 kB

VmData:    50056 kB

VmStk:      132 kB

VmExe:       88 kB

VmLib:     3024 kB

VmPTE:       26 kB

VmPMD:        0 kB

VmSwap:        0 kB

Threads: 7

SigQ: 0/3918

SigPnd: 0000000000000000

ShdPnd: 0000000000000000

SigBlk: 0000000000000000

SigIgn: 0000000000000006

SigCgt: 0000000180000000

CapInh: 0000000000000000

CapPrm: 0000003fffffffff

CapEff: 0000003fffffffff

CapBnd: 0000003fffffffff

CapAmb: 0000000000000000

NoNewPrivs: 0

Speculation_Store_Bypass: unknown

Cpus_allowed: 3

Cpus_allowed_list: 0-1

voluntary_ctxt_switches: 32

nonvoluntary_ctxt_switches: 8

关于内存相关的参数,含义如下:

/proc/pid/maps

root@WDFG201-D:/proc/280 # cat maps

00010000-00026000 r-xp 00000000 1f:05 1388       /sbin/gc_event_agent

00035000-00036000 r--p 00015000 1f:05 1388       /sbin/gc_event_agent

00036000-00037000 rw-p 00016000 1f:05 1388       /sbin/gc_event_agent

00037000-00058000 rw-p 00000000 00:00 0          [heap]

b3600000-b3621000 rw-p 00000000 00:00 0

b3621000-b3700000 ---p 00000000 00:00 0

b3700000-b3721000 rw-p 00000000 00:00 0

b3721000-b3800000 ---p 00000000 00:00 0

b3800000-b3a00000 r--s 00000000 00:05 32769      /SYSV610d07d2 (deleted) ///共享区,一般由mmap映射

b3a00000-b3a21000 rw-p 00000000 00:00 0  

b3a21000-b3b00000 ---p 00000000 00:00 0

b3b67000-b3b68000 ---p 00000000 00:00 0

b3b68000-b4368000 rw-p 00000000 00:00 0

b4368000-b4369000 ---p 00000000 00:00 0

b4369000-b4b69000 rw-p 00000000 00:00 0

b4b69000-b4b6a000 ---p 00000000 00:00 0

b4b6a000-b536a000 rw-p 00000000 00:00 0

b536a000-b536b000 ---p 00000000 00:00 0

b536b000-b5b6b000 rw-p 00000000 00:00 0

b5b6b000-b5b6c000 ---p 00000000 00:00 0

b5b6c000-b636c000 rw-p 00000000 00:00 0

b636c000-b636d000 ---p 00000000 00:00 0

b636d000-b6b6d000 rw-p 00000000 00:00 0

b6b6d000-b6c9a000 r-xp 00000000 1f:05 396        /lib/libc-2.29.so

b6c9a000-b6caa000 ---p 0012d000 1f:05 396        /lib/libc-2.29.so

b6caa000-b6cac000 r--p 0012d000 1f:05 396        /lib/libc-2.29.so

b6cac000-b6cad000 rw-p 0012f000 1f:05 396        /lib/libc-2.29.so

b6cad000-b6cb0000 rw-p 00000000 00:00 0  //没有文件名的条目,实际上是上一个有文件名的.bss段映射,它们并不在文件中占用空间,需要在加载时清零。所以做文件映射就不能实现该功能(因为文件里没有对应的内容),所以这里其实是映射到了一个匿名的私有空间,逻辑地址空间和前面的连续。

b6cb0000-b6ccd000 r-xp 00000000 1f:05 467        /lib/libgcsutils.so

b6ccd000-b6cdc000 ---p 0001d000 1f:05 467        /lib/libgcsutils.so

b6cdc000-b6cdd000 r--p 0001c000 1f:05 467        /lib/libgcsutils.so

b6cdd000-b6cde000 rw-p 0001d000 1f:05 467        /lib/libgcsutils.so

b6cde000-b6ce9000 r-xp 00000000 1f:05 466        /lib/libgcsmsg.so

b6ce9000-b6cf9000 ---p 0000b000 1f:05 466        /lib/libgcsmsg.so

b6cf9000-b6cfa000 r--p 0000b000 1f:05 466        /lib/libgcsmsg.so

b6cfa000-b6cfb000 rw-p 0000c000 1f:05 466        /lib/libgcsmsg.so

b6cfb000-b6cfc000 r-xp 00000000 1f:05 498        /lib/liblog.so

b6cfc000-b6d0b000 ---p 00001000 1f:05 498        /lib/liblog.so

b6d0b000-b6d0c000 r--p 00000000 1f:05 498        /lib/liblog.so

b6d0c000-b6d0d000 rw-p 00001000 1f:05 498        /lib/liblog.so

b6d0d000-b6d57000 r-xp 00000000 1f:05 504        /lib/libmdm.so

b6d57000-b6d67000 ---p 0004a000 1f:05 504        /lib/libmdm.so

b6d67000-b6d68000 r--p 0004a000 1f:05 504        /lib/libmdm.so

b6d68000-b6da3000 rw-p 0004b000 1f:05 504        /lib/libmdm.so

b6da3000-b6db3000 rw-p 00000000 00:00 0

b6db3000-b6e43000 r-xp 00000000 1f:05 502        /lib/libm-2.29.so

b6e43000-b6e52000 ---p 00090000 1f:05 502        /lib/libm-2.29.so

b6e52000-b6e53000 r--p 0008f000 1f:05 502        /lib/libm-2.29.so

b6e53000-b6e54000 rw-p 00090000 1f:05 502        /lib/libm-2.29.so

b6e54000-b6e7d000 r-xp 00000000 1f:05 462        /lib/libgc.so

b6e7d000-b6e8c000 ---p 00029000 1f:05 462        /lib/libgc.so

b6e8c000-b6e8d000 r--p 00028000 1f:05 462        /lib/libgc.so

b6e8d000-b6e8e000 rw-p 00029000 1f:05 462        /lib/libgc.so

b6e8e000-b6ef2000 r-xp 00000000 1f:05 426        /lib/libevent-2.1.so.7.0.0

b6ef2000-b6f01000 ---p 00064000 1f:05 426        /lib/libevent-2.1.so.7.0.0

b6f01000-b6f02000 r--p 00063000 1f:05 426        /lib/libevent-2.1.so.7.0.0

b6f02000-b6f03000 rw-p 00064000 1f:05 426        /lib/libevent-2.1.so.7.0.0

b6f03000-b6f19000 r-xp 00000000 1f:05 586        /lib/libpthread-2.29.so

b6f19000-b6f28000 ---p 00016000 1f:05 586        /lib/libpthread-2.29.so

b6f28000-b6f29000 r--p 00015000 1f:05 586        /lib/libpthread-2.29.so

b6f29000-b6f2a000 rw-p 00016000 1f:05 586        /lib/libpthread-2.29.so

b6f2a000-b6f2c000 rw-p 00000000 00:00 0

b6f2c000-b6f4c000 r-xp 00000000 1f:05 365        /lib/ld-2.29.so

b6f57000-b6f58000 rw-s 00000000 00:05 0          /SYSV000004d2 (deleted)

b6f58000-b6f5c000 rw-p 00000000 00:00 0

b6f5c000-b6f5d000 r--p 00020000 1f:05 365        /lib/ld-2.29.so

b6f5d000-b6f5e000 rw-p 00021000 1f:05 365        /lib/ld-2.29.so

beb13000-beb34000 rw-p 00000000 00:00 0          [stack]

becd0000-becd1000 r-xp 00000000 00:00 0          [sigpage]

ffff0000-ffff1000 r-xp 00000000 00:00 0          [vectors]

输出信息依次为:

第一列:本段在虚拟内存中的地址范围

第二列:本段的权限

第三列:偏移地址,即指本段映射地址在文件中的偏移

第四列:主设备号和次设备号

第五列:文件索引节点号

第六列:映射的文件名

例:00010000-00026000 r-xp 00000000 1f:05 1388       /sbin/gc_event_agent

00010000-00026000 :是该虚拟内存段的开始和结束位置

r-xp内存段的权限,分别是可读、可写、可运行、私有或共享,最后一位p代表私有,s代表共享/r-xp:代码段;r--p:常量段;rw-p:全局变量;---p:两个LOAD区间中空闲的内存空间,为栈保护区,可以达到栈溢出保护的作用;

00000000该虚拟内存段起始地址在对应的映射文件中以页为单位的偏移量,对匿名映射,它等于0或者vm_start/PAGE_SIZE

1f:05文件的主设备号和次设备号。对匿名映射来说,因为没有文件在磁盘上,所以没有设备号,始终为00:00。对有名映射来说,是映射的文件所在设备的设备号。

1388被映射到虚拟内存的文件的索引节点号,通过该节点可以找到对应的文件,对匿名映射来说,因为没有文件在磁盘上,所以没有节点号,始终为00:00。

/sbin/gc_event_agent被映射到虚拟内存的文件名称。后面带(deleted)的是内存数据,可以被销毁。对有名来说,是映射的文件名。对匿名映射来说,是此段虚拟内存在进程中的角色。[stack]表示在进程中作为栈使用,[heap]表示堆。其余情况则无显示。

/proc/pid/smaps

/proc/pid/smaps文件是基于/proc/pid/maps的扩展,它展示了一个进程的内存消耗,比同一个目录下的maps文件更为详细。

root@WDFG201-D:/proc/274 # cat smaps

00010000-00026000 r-xp 00000000 1f:04 1546       /sbin/gc_event_agent

Size:                 88 kB

KernelPageSize:        4 kB

MMUPageSize:           4 kB

Rss:                  88 kB

Pss:                  88 kB

Shared_Clean:          0 kB

Shared_Dirty:          0 kB

Private_Clean:        88 kB

Private_Dirty:         0 kB

Referenced:           88 kB

Anonymous:             0 kB

LazyFree:              0 kB

AnonHugePages:         0 kB

ShmemPmdMapped:        0 kB

Shared_Hugetlb:        0 kB

Private_Hugetlb:       0 kB

Swap:                  0 kB

SwapPss:               0 kB

Locked:                0 kB

VmFlags: rd ex mr mw me dw

00035000-00036000 r--p 00015000 1f:04 1546       /sbin/gc_event_agent

Size:                  4 kB

KernelPageSize:        4 kB

MMUPageSize:           4 kB

Rss:                   4 kB

Pss:                   4 kB

Shared_Clean:          0 kB

Shared_Dirty:          0 kB

Private_Clean:         0 kB

Private_Dirty:         4 kB

Referenced:            4 kB

Anonymous:             4 kB

LazyFree:              0 kB

AnonHugePages:         0 kB

ShmemPmdMapped:        0 kB

Shared_Hugetlb:        0 kB

Private_Hugetlb:       0 kB

Swap:                  0 kB

SwapPss:               0 kB

Locked:                0 kB

VmFlags: rd mr mw me dw ac

00036000-00037000 rw-p 00016000 1f:04 1546       /sbin/gc_event_agent

Size:                  4 kB

KernelPageSize:        4 kB

MMUPageSize:           4 kB

Rss:                   4 kB

Pss:                   4 kB

Shared_Clean:          0 kB

Shared_Dirty:          0 kB

Private_Clean:         0 kB

Private_Dirty:         4 kB

Referenced:            4 kB

Anonymous:             4 kB

LazyFree:              0 kB

AnonHugePages:         0 kB

ShmemPmdMapped:        0 kB

Shared_Hugetlb:        0 kB

Private_Hugetlb:       0 kB

Swap:                  0 kB

SwapPss:               0 kB

Locked:                0 kB

VmFlags: rd wr mr mw me dw ac

Size:虚拟内存空间大小。但是这个内存值不一定是物理内存实际分配的大小,因为在用户态上,虚拟内存总是延迟分配的。这个值计算也非常简单,就是该VMA的开始位置减结束位置。

Rss:是实际分配的内存,这部分物理内存已经分配,不需要缺页中断就可以使用的。

Pss(proportional set size):是平摊计算后的实际物理使用内存(有些内存会和其他进程共享,例如mmap进来的)。
Referenced:当前页面被标记为已引用或者包含匿名映射(The amount of memory currently marked as referenced or a mapping associated with a file may contain anonymous pages)。

Anonymous:匿名映射的物理内存,这部分内存不来自于文件的内存大小。

ShmemPmdMapped:PMD页面已经被映射的共享(shmem / tmpfs)内存量。在官方文档中,这样解释:"ShmemPmdMapped" shows the ammount of shared (shmem/tmpfs) memory backed by huge pages.

Shared/Private_Hugetlb:由hugetlbfs页面支持的内存使用量,由于历史原因,该页面未计入“ RSS”或“ PSS”字段中。 并且这些没有包含在Shared/Private_Clean/Dirty 字段中。

Swap:存在于交换分区的数据大小(如果物理内存有限,可能存在一部分在主存一部分在交换分区)

SwapPss:这个我并没有找到对应解释,但从源码可以得知,计算逻辑就跟pss一样,只不过针对的是交换分区的内存。

KernelPageSize:内核一页的大小
MMUPageSize:MMU页大小,大多数情况下,和KernelPageSize大小一样。

Locked:常驻物理内存的大小,这些页不会被换出。

THPeligible:映射是否符合分配THP的条件。如果为true,则为1,否则为0。 它仅显示当前状态。

THP,透明大页(Transparent Huge Pages),RHEL 6 开始引入,目的是使用更大的内存页面(memory page size) 以适应越来越大的系统内存,让操作系统可以支持现代硬件架构的大页面容量功能。与标准大页的区别在于分配机制,标准大页管理是预分配的方式,而透明大页管理则是动态分配的方式。

VmFlags:表示与特定虚拟内存区域关联的内核标志

注释:

段名

存储属性

内存分配

代码段
.text

存放可执行程序的指令,存储态和运行态都有

静态

数据段
.data

存放已初始化(非零初始化的全局变量和静态局部变量)的数据,存储态和运行态都有

静态

bss段
.bss

存放未初始化(未初始化或者0初始化的全局变量和静态局部变量)的数据,存储态和运行态都有

静态


heap

动态分配内存,需要通过malloc手动申请,free手动释放,适合大块内存。容易造成内存泄漏和内存碎片。运行态才有。

动态


stack

存放函数局部变量和参数以及返回值,函数返回后,由操作系统立即回收。栈空间不大,使用不当容易栈溢出。运行态才有

静态

  • 13
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值