嵌入式linux一般会有裁剪,查看内存的工具和命令提供的信息可能没有那么全,该文记录下linux系统中查看内存的方法
下面的命令显示的内容可能会根据机器的内核和CPU的架构的不同而有一些出入,可能有些项名字不同或者直接没有
本文命令运行的机器信息
Linux imx6 4.14.78-imx_4.14.78_1.0.0_ga+g66620c3 #1 SMP PREEMPT Wed Jul 17 08:17:08 UTC 2019 armv7l GNU/Linux
Linux ubuntu 4.4.0-203-generic #235-Ubuntu SMP Tue Feb 2 02:49:08 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
查看系统内存
free命令
root@imx6:~# free
total used free shared buffers cached
Mem: 115316 54716 60600 4368 556 18684
-/+ buffers/cache: 35476 79840
Swap: 64816 0 64816
free 命令显示的内存大小默认单位为kb,如果想用单位M查看使用 free -m,但是不一定都支持
total 有Memtotal和Swaptotal, Memtotal表示总内存大小,Swaptotal表示允许启用内存交换到硬盘的总大小(即交换分区),一般是当内存不够用时才会被用到
used 正在被使用的内存 有文章说uesd=total - free - buffer - cache,但是我的系统并不是这样而是 used = total-free
free 未被使用的空闲内存
shared 被系统中的tmpfs文件系统使用的内存
buffer 内核使用的缓冲区,有文章说是从磁盘读取的缓存,以减少磁盘的IO,这个值不应该很大
cached page与slab缓存
在开发过程中发现,当我前台运行程序时,free会慢慢减少,放一晚后free只剩余2M多,buffer和cache变大,此程序本身的内存大小并没有变化,如果是后台运行就没有变化。具体原因没有研究清楚,不知道是不是标准输出的原因
查看 /proc/meminfo
其实free命令得到的内存信息是从/proc/meminfo来的
root@imx6:~#cat /proc/meminfo
MemTotal: 115316 kB
MemFree: 59872 kB
MemAvailable: 72544 kB
Buffers: 736 kB
Cached: 18824 kB
SwapCached: 0 kB
Active: 13696 kB
Inactive: 12880 kB
Active(anon): 2816 kB
Inactive(anon): 8580 kB
Active(file): 10880 kB
Inactive(file): 4300 kB
Unevictable: 0 kB
Mlocked: 0 kB
HighTotal: 0 kB
HighFree: 0 kB
LowTotal: 115316 kB
LowFree: 59872 kB
SwapTotal: 64816 kB
SwapFree: 64816 kB
Dirty: 20 kB
Writeback: 0 kB
AnonPages: 7036 kB
Mapped: 15844 kB
Shmem: 4376 kB
Slab: 12692 kB
SReclaimable: 2920 kB
SUnreclaim: 9772 kB
KernelStack: 736 kB
PageTables: 704 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 122472 kB
Committed_AS: 183088 kB
VmallocTotal: 1949696 kB
VmallocUsed: 0 kB
VmallocChunk: 0 kB
CmaTotal: 0 kB
CmaFree: 0 kB
MemTotal 表示总内存大小
MemFree 未被使用的空闲内存
MemAvailable 当前可用内存,是系统计算出来的一个大致的值,空闲内存+可替换的缓存
Buffers: 内核使用的缓冲区,同free里的项buffers
cached: page与slab缓存,同free里的项cached
SwapCached:从ROM交换出去存放在swapfile中的内存大小
Dirty: 脏页大小,被write入修改过需要写回到磁盘的信息
Active: 最近被使用的内存,在没有必要情况下这部分内存不会被收回
Inactive: 曾经被使用的内存最近没有被使用,这部分是可能会被回收的内存
Active(anon): 分配给tmpfs文件系统的匿名文件的内存大小,这些文件都是存在内存中的
Inactive(anon):同理
Active(file): 正常文件缓存内存大小,或者说自上一个回收周期起的正常文件缓存内存大小
Inactive(file): 同理
Unevictable: 应该可以回收的内存但是没有回收,因为被锁在了用户空间进程中
Mlocked: 不可回收的内存,因为被锁在了用户空间进程中
LowTotal: Lowmem内存大小,内核优先使用这部分内存
HighTotal: Hignmem的内存大小,内存大于(860M)的部分属于Hignmem,CPU间接访问这块内存,用户空间进制优先使用这部分内存
LowFree与HighFree: 对应LowTotal与HighTotal空闲的内存
Writeback: 正在被写回磁盘的内存
AnonPages: 映射到用户空间的非文件的内存大小
Mapped: 映射到内存中的文件(例如库文件)的大小
Shmem: 等于free中的shared,被系统中的tmpfs文件系统使用的内存
Slab: 内核数据结构缓存 Slab=SReclaimable + SUnreclaim
SReclaimable: Slab内存中可能会被回收的部分内存
SUnreclaim: Slab内存中不能被回收的部分内存
KernelStack: 分配给内核堆栈的内存
PageTables: 专用于最低层次的页表的内存
NFS_Unstable: 网络文件系统接收到但是还逗留在内存尚未写入到磁盘的内存大小
Bounce: 用于块设备的Bounce缓存区
WritebackTmp: 文件系统用在用户空间中用于临时回写缓冲区的内存
CommitLimit: 当前系统可分配的最大内存
Committed_AS: 为满足系统所有当前需求而估计的内存数量
VmallocTotal: 虚拟内存总大小
VmallocUsed: 已用虚拟内存,linux4.4版本后已经不再使用,转为硬编码
VmallocChunk: 可用虚拟内存的最大连续块大小
CmaTotal: CMA(Contiguous Memory Allocator)页大小
CmaFree: 可用的CMA页大小
使用top命令
下面是我的ubuntu 16.04虚拟机的top命令显示
gateway@ubuntu:~$top
top - 13:31:36 up 5 days, 21:48, 1 user, load average: 1.93, 1.93, 1.97
Tasks: 241 total, 1 running, 240 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.0 us, 0.5 sy, 0.0 ni, 98.5 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 8166268 total, 431996 free, 3375120 used, 4359152 buff/cache
KiB Swap: 8385532 total, 8370688 free, 14844 used. 4326988 avail MemPID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
7002 root 20 0 501936 125060 46280 S 22.2 1.5 26:51.63 Xorg
9549 gateway 20 0 4215540 1.587g 57796 S 22.2 20.4 153:53.05 java
7700 gateway 20 0 1551496 179504 70020 S 16.7 2.2 19:31.58 compiz
193 root 20 0 0 0 0 S 5.6 0.0 1:01.65 jbd2/sda1-8
1 root 20 0 119676 5584 4004 S 0.0 0.1 0:04.66 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.18 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:04.53 ksoftirqd/0
5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:+
7 root 20 0 0 0 0 S 0.0 0.0 2:40.68 rcu_sched
8 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_bh
imx6板子的显示内容相对少一些
root@imx6:~#top
Mem: 66484K used, 48832K free, 4584K shrd, 5064K buff, 25376K cached
CPU: 0% usr 16% sys 0% nic 83% idle 0% io 0% irq 0% sirq
Load average: 0.03 0.03 0.01 1/92 3341
PID PPID USER STAT VSZ %VSZ %CPU COMMAND
3341 3339 root R 2784 2% 17% top
3118 2291 root S 109m 97% 0% {11} work1
2291 1 root S 40984 35% 0% Daemon
2293 2291 root S 24684 21% 0% Daemon
2298 2293 root S 23064 20% 0% {8} HOST -b 115200 -f x -p /dev/ttymxc
我们已ubuntu虚拟机显示说明:
第一行:top - 13:31:36 up 5 days, 21:48, 1 user, load average: 1.93, 1.93, 1.97
13:31:36 up 5 days, 21:48 说明机器起来的时间,运行了多久
1 user 表示多少个用户登录
load average: 1.93, 1.93, 1.97 表示平均负载大小
第二行:表示有多少个进程在运行以及他们的状态
第三行:CPU运行信息,后续的数值是百分比
us user 表示CPU执行用户空间进程时间;
sy system 表示CPU执行内核空间进程时间
ni nice表示CPU执行手动设置了nice优先级的用户空间进程时间
id idle 表示CPU处于空闲状态的时间
wa IO-wait 表示系统等待IO完成时间
hi 表示处理硬中断的时间
si 表示处理软中断的时间
st: 管理程序从当前虚拟机拿走的执行时间,一般是当本机高负载时,管理程序窃取本机的执行时间补偿给在该管理程序下
第四行:物理内存使用情况
第五行:Swap内存使用情况
下方每列的含义是:
PID: 进程号
USER: 进程的所有者的用户名
PR: 进程优先级 值越大优先级越低
NI: 进程的nice值
VIRT: 进程使用的虚拟内存大小
RES: 进程使用的实际物理内存大小
SHR: 进程使用的共享内存大小,参考前面的shared,Shmem
S: 进程的状态,可能值请查看下面的字段说明
D:uninterruptible sleep 参数D的原因一般是进程在等待IO,例如磁盘IO,网络IO
R:Running
S:Sleeping
T:Stoped 暂停状态 ,如果向进程发送了SIGSTOP信号,只要进程不是处于D的状态,那么
此进程就会进入Stoped状态
t:Traced 被跟踪状态,比如使用gdb调试时,当运行到断点处,进程就处于Traced状态
Z:Zombie 僵尸,本身进程已经终止,但是没有被父进程回收,僵尸进程会占用process table slot,如果太多会导致系统无法创建新的进程
使用vmstat命令
gateway@ubuntu:~$vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 5953736 250908 1348164 0 0 1343 629 324 472 8 6 85 1 0
这里也有很多项,我们按类型拆分来
- procs
r: runnable状态进程的数量
b:uninterruptible sleep状态进程的数量
- memory
swap:交换出去的内存大小
free:未使用的内存大小
buff:内核使用的缓冲区,等同于proc/meminfo中的Buffers
cache:page与slab缓存,等同于proc/meminfo中的Cached
- swap
si:从swap空间交换回RAM的内存大小
so:RAM交换到swap空间的内存大小
- IO
bi:从块设备接收到的块大小
bo:发送给块设备的块大小
- system
in:每秒发送总段的数量
cs:每秒的上下文切换数量,一次上下位切换表示从内核态切换到用户态
- cpu
cpu的值都是百分比
请参考上面top命令CPU信息那一块的内容
查看单个进程的内存信息
查看 /proc/PID/status
root@imx6:~# cat /proc/3533/status
Name: 11
Umask: 0022
State: S (sleeping)
Tgid: 3533
Ngid: 0
Pid: 3533
PPid: 2291
TracerPid: 0
Uid: 0 0 0 0
Gid: 0 0 0 0
FDSize: 32
Groups: 0
VmPeak: 115764 kB
VmSize: 95268 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 9096 kB
VmRSS: 9080 kB
RssAnon: 1304 kB
RssFile: 6752 kB
RssShmem: 1024 kB
VmData: 83060 kB
VmStk: 132 kB
VmExe: 1212 kB
VmLib: 7704 kB
VmPTE: 38 kB
VmPMD: 0 kB
VmSwap: 0 kB
Threads: 9
SigQ: 3/892
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000010000
SigIgn: 0000000000001000
SigCgt: 0000000180000000
CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
NoNewPrivs: 0
Speculation_Store_Bypass: unknown
Cpus_allowed: 1
Cpus_allowed_list: 0
voluntary_ctxt_switches: 1965
nonvoluntary_ctxt_switches: 469
Name:运行这个进程的命令,如果字符长度超过TASK_COMM_LEN(16),超过部分会被截断
State:进程的状态,可参见前面讲过的进程的集中状态
Tgid:进程组号
Ngid:NUMA组号
Pid:进程号
PPid:父进程号
TracerPid:跟踪该进程的进程号
Uid,Gid:Real, effective, saved set, and filesystem UIDs (GIDs).
FDSize:当前进程文件描述符槽分配的数量
Groups:Supplementary group list.
Vmpeak :虚拟内存峰值(Peak virtual memory size.)
Vmsize:虚拟内存大小
Vmlck:被锁住的虚拟内存大小
Vmpin:因为某些东西的需要不能移动的固定内存大小
VmHWM:实际使用的物理内存锋值,这个值可能是不准确的
VmRSS:当前实际使用的物理内存,VmRSS=RssAnon+RssFile+RssShmem
RssAnon:实际使用匿名内存大小
RssFile:实际使用文件映射内存大小
RssShmem:实际共享内存使用大小
VmData,VmStk,VmExe:数据,堆栈,文本段的大小,该值不可能不准确
Vmlib:共享库的大小
VmPTE:页表大小
VmPMD:二级页表大小
VmSwap:通过匿名的私有页交换出去的内存;shmem交换使用的不包括在这里面
Threads:进程中线程的数量
SigQ:此字段包含两个斜杠分隔的数字,它们与真实用户ID的排队信号相关,这个过程的。第一个是这个真实用户ID当前排队信号的数量,第二个是这个进程排队信号数量的资源限制(请参阅getrlimit(2)中RLIMIT_SIGPENDING的描述)。
SigPnd,ShdPng:线程和整个进程挂起的信号掩码
SigBlk,SigIgn,SigCgt :表示信号被阻塞、忽略和捕获的掩码