LinuxSys:内存管理-内存占用查看
本文采用知识共享署名 4.0 国际许可协议进行许可,转载时请注明原文链接,图片在使用时请保留全部内容,可适当缩放并在引用处附上图片所在的文章链接。
本文采用知识共享署名 4.0 国际许可协议进行许可,转载时请注明原文链接,图片在使用时请保留全部内容,可适当缩放并在引用处附上图片所在的文章链接。
内存使用查看
设备内存查看
cat /proc/meminfo
- MemTotal
系统从加电开始到引导完成,firmware/BIOS要保留一些内存,kernel本身要占用一些内存,最后剩下可供kernel支配的内存就是MemTotal。这个值在系统运行期间一般是固定不变的。
- MemFree
表示系统尚未使用的内存。(MemTotal-MemFree)就是已被用掉的内存。
- MemAvailable
有些应用程序会根据系统的可用内存大小自动调整内存申请的多少,所以需要一个记录当前可用内存数量的统计值,MemFree并不适用,因为MemFree不能代表全部可用的内存,系统中有些内存虽然已被使用但是可以回收的,比如cache/buffer、slab都有一部分可以回收,所以这部分可回收的内存加上MemFree才是系统可用的内存,即MemAvailable。/proc/meminfo中的MemAvailable是内核使用特定的算法估算出来的,这是一个估计值,并不精确。
free -h
total 总物理内存
used 已经使用的物理内存
free 没有使用过的物理内存
shared 多进程共享内存
buff/cache 读写缓存内存,这部分内存是当空闲来用的,当free内存不足时,linux内核会将此内存释放
available 还可以被 应用程序 使用的物理内存
进程内存查看
top
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
|
|
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
-
取值为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
当overcommit_memory=2的时候,它一般代表的是系统中总的内存的百分比。
overcommit_memory
/proc/meminfo
CommitLimit
虚拟内存限值(CommitLimit)
CommitLimit = SwapTotal + MemTotal * overcommit_ratio
总的虚拟内存 = 总的交换分区 + 总的物理内存 * overcommit_ratio
Committed_AS
Committed_AS代表了系统已经分配的内存情况。
内存管理系统模块
-
用户程序(Mutator)- 可以通过分配器创建对象或者更新对象持有的指针;
-
内存分配器(Allocator)— 处理用户程序的的内存分配请求;- 垃圾收集器(Collector)- 标记内存中的对象并回收不需要的内存;
参考: