内存管理:内存占用查看

内存管理:内存占用查看

本文采用知识共享署名 4.0 国际许可协议进行许可,转载时请注明原文链接,图片在使用时请保留全部内容,可适当缩放并在引用处附上图片所在的文章链接。

内存使用查看

设备内存查看

cat /proc/meminfo

toybrick@debian10:~/Rockchip/zyh/aarch64-rk3399pro-linux$ cat /proc/meminfo

MemTotal:        2005872 kB
MemFree:          270656 kB
MemAvailable:    1284680 kB
  • MemTotal

系统从加电开始到引导完成,firmware/BIOS要保留一些内存,kernel本身要占用一些内存,最后剩下可供kernel支配的内存就是MemTotal。这个值在系统运行期间一般是固定不变的。

  • MemFree

表示系统尚未使用的内存。(MemTotal-MemFree)就是已被用掉的内存。

  • MemAvailable

有些应用程序会根据系统的可用内存大小自动调整内存申请的多少,所以需要一个记录当前可用内存数量的统计值,MemFree并不适用,因为MemFree不能代表全部可用的内存,系统中有些内存虽然已被使用但是可以回收的,比如cache/buffer、slab都有一部分可以回收,所以这部分可回收的内存加上MemFree才是系统可用的内存,即MemAvailable。/proc/meminfo中的MemAvailable是内核使用特定的算法估算出来的,这是一个估计值,并不精确。

free -h

toybrick@debian10:~/Rockchip/zyh/aarch64-rk3399pro-linux$ free -h

              total        used        free      shared  buff/cache   available
Mem:          1.9Gi       166Mi       842Mi        35Mi       950Mi       1.7Gi
Swap:            0B          0B          0B

total 总物理内存

used 已经使用的物理内存

free 没有使用过的物理内存

shared 多进程共享内存

buff/cache 读写缓存内存,这部分内存是当空闲来用的,当free内存不足时,linux内核会将此内存释放

available 还可以被 应用程序 使用的物理内存

进程内存查看

top

  toybrick@debian10:~/Rockchip/zyh/aarch64-rk3399pro-linux$ top
  
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                                 
20314 root      20   0 1557720  32712  15240 S  82.0   1.6 143:39.94 T3RHeadDetectTe                                                         

PID:进程的ID

USER:进程所有者

PR:进程的优先级别,越小越优先被执行

NInice:值

VIRT:进程占用的虚拟内存

RES:进程占用的物理内存

SHR:进程使用的共享内存

S:进程的状态。S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值为负数

%CPU:进程占用CPU的使用率

%MEM:进程使用的物理内存和总内存的百分比

TIME+:该进程启动后占用的总的CPU时间,即占用CPU使用时间的累加值。

COMMAND:进程启动命令名称

常用的命令:

P:按%CPU使用率排行

T:按MITE+排行

M:按%MEM排行

cat /proc/$_PID/status

Name: Log2Hostflush
Umask: 0022
State: D (disk sleep)-----------------------表示此时线程处于sleeping,并且是uninterruptible状态的wait。

Tgid: 157-----------------------------------线程组的主pid为157。
Ngid: 0
Pid: 159------------------------------------线程自身的pid为159。
PPid: 1-------------------------------------线程组是由init进程创建的。
TracerPid: 0
Uid: 0 0 0 0
Gid: 0 0 0 0
FDSize: 256---------------------------------表示到目前为止进程使用过的描述符总数。
Groups: 0 10
VmPeak: 1393220 kB--------------------------虚拟内存峰值大小。
VmSize: 1390372 kB--------------------------当前使用中的虚拟内存,小于VmPeak。
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 47940 kB-----------------------------RSS峰值。
VmRSS: 47940 kB-----------------------------RSS实际使用量=RSSAnon+RssFile+RssShmem。
RssAnon: 38700 kB
RssFile: 9240 kB
RssShmem: 0 kB
VmData: 366648 kB--------------------------进程数据段共366648KB。
VmStk: 132 kB------------------------------进程栈一共132KB。
VmExe: 84 kB-------------------------------进程text段大小84KB。
VmLib: 11488 kB----------------------------进程lib占用11488KB内存。
VmPTE: 1220 kB
VmPMD: 0 kB
VmSwap: 0 kB
Threads: 40-------------------------------进程中一个40个线程。
SigQ: 0/3142------------------------------进程信号队列最大3142,当前没有pending状态的信号。
SigPnd: 0000000000000000------------------没有进程pending,所以位图为0。
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000006------------------被忽略的信号,对应信号为SIGINT和SIGQUIT,这两个信号产生也不会进行处理。
SigCgt: 0000000180000800------------------已经产生的信号位图,对应信号为SIGUSR2、以及实时信号32和33。
CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
Cpus_allowed: 1---------------------------仅在第1个cpu上执行。
Cpus_allowed_list: 0
voluntary_ctxt_switches: 2377-------------线程主动切换2377次,被动切换5次。
nonvoluntary_ctxt_switches: 5

OOM(Out Of Memory Killer)

Linux下允许程序申请比系统可用内存更多的内存,这个特性叫Overcommit。这样做是出于优化系统考虑,因为不是所有的程序申请了内存就立刻使用的,当你使用的时候说不定系统已经回收了一些资源了。当用到这个Overcommit给你的内存的时候,系统还没有资源的话,OOM killer就跳出来了。

OOM Killer 是Out Of Memory Killer的简称。OOMKiller功能作为确保内存的最终手段,可以在耗尽系统内存或交换区后,向进程发送信号,强制终止该进程。 OOM Killer通过终止进程来确保空闲内存,以确保Linux系统有足够的系统保持稳定的运行。而要kill哪个进程,则是有一套算法的。简单的理解就是,计算每一个进程的内存使用得到一个分数,分数最高的就会被干掉。

什么时候跳出来

先看第一个问题,它什么时候会跳出来。是不是malloc返回NULL的时候跳出来呢?不是的,malloc的manpage里有下面一段话:

By default, Linux follows an optimistic memory allocation strategy.
This means that when malloc() returns non-NULL there is no guarantee
that the memory really is available. This is a really bad bug. In
case it turns out that the system is out of memory, one or more processes
will be killed by the infamous OOM killer. In case Linux is
employed under circumstances where it would be less desirable to suddenly
lose some randomly picked processes, and moreover the kernel version
is sufficiently recent, one can switch off this overcommitting
behavior using a command like:

# echo 2 > /proc/sys/vm/overcommit_memory

上面一段话告诉我们,Linux中malloc返回非空指针,并不一定意味着指向的内存就是可用的,Linux下允许程序申请比系统可用内存更多的内存,这个特性叫Overcommit。这样做是出于优化系统考虑,因为不是所有的程序申请了内存就立刻使用的,当你使用的时候说不定系统已经回收了一些资源了。不幸的是,当你用到这个Overcommit给你的内存的时候,系统还没有资源的话,OOM killer就跳出来了。

/proc/sys/vm/

overcommit_memory

cat /proc/sys/vm/overcommit_memory
echo 0 > /proc/sys/vm/overcommit_memory

# 当overcommit_memory=0 允许进程轻微过量使用内存,但对于大量过载请求则不允许(默认)
# 当overcommit_memory=1 永远允许进程overcommit
# 当overcommit_memory=2 永远禁止overcommit
  • 取值为0,系统在为应用进程分配虚拟地址空间时,会判断当前申请的虚拟地址空间大小是否超过剩余内存大小,如果超过,则虚拟地址空间分配失败。因此,也就是如果进程本身占用的虚拟地址空间比较大或者剩余内存比较小时,fork、malloc等调用可能会失败。

  • 取值为1,系统在为应用进程分配虚拟地址空间时,完全不进行限

  • 制,这种情况下,避免了fork可能产生的失败,但由于malloc是先分配虚拟地址空间,而后通过异常陷入内核分配真正的物理内存,在内存不足的情况下,这相当于完全屏蔽了应用进程对系统内存状态的感知,即malloc总是能成功,一旦内存不足,会引起系统OOM杀进程,应用程序对于这种后果是无法预测的

  • 取值为2,则是根据系统内存状态确定了虚拟地址空间的上限,由于很多情况下,进程的虚拟地址空间占用远大小其实际占用的物理内存,这样一旦内存使用量上去以后,对于一些动态产生的进程(需要复制父进程地址空间)则很容易创建失败,如果业务过程没有过多的这种动态申请内存或者创建子进程,则影响不大,否则会产生比较大的影响

overcommit_memory=2的使用场景:

CommitLimit为当前系统可以申请的总内存,Committed_AS为当前已经申请的内存,记住是申请。

因此当你的free查看有很多大量可用的内存的时候,实际Committed_AS可能已经申请了大量的内存了,在vm.overcommit_memory 2模式下,

后续的程序可以申请的剩余内存为CommitLimit - Commited_AS了。而vm.overcommit_memory设置为2一般是建议当Swap大于物理内存的时候才进行设置。

overcommit_ratio

cat /proc/sys/vm/overcommit_ratio
echo 50  > /proc/sys/vm/overcommit_ratio

当overcommit_memory=2的时候,它一般代表的是系统中总的内存的百分比。

overcommit_memory

cat /proc/sys/vm/overcommit_memory
echo 0  > /proc/sys/vm/overcommit_ratio

/proc/meminfo

cat /proc/meminfo

CommitLimit:  1002936 kB
Committed_AS: 1345984 kB

CommitLimit

虚拟内存限值(CommitLimit)

CommitLimit = SwapTotal + MemTotal * overcommit_ratio

总的虚拟内存 = 总的交换分区 + 总的物理内存 * overcommit_ratio

Committed_AS

Committed_AS代表了系统已经分配的内存情况。

内存管理系统模块

  • 用户程序(Mutator)- 可以通过分配器创建对象或者更新对象持有的指针;

  • 内存分配器(Allocator)— 处理用户程序的的内存分配请求;- 垃圾收集器(Collector)- 标记内存中的对象并回收不需要的内存;

参考:

Linux OOM-killer机制(out of memory)

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

002237

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值