centos 内存回收 内存回收机制

很多朋友对于centos 内存回收和内存回收机制不太懂,今天就由小编来为大家分享,希望可以帮助到大家,下面一起来看看吧!

CentOS技巧减小Linuxswap分区的方法

用虚拟机玩Linux时经常发生Linux硬盘空间不足的情况,而宿主机硬盘空间又吃紧,怎么办?

很多童鞋给Linux分配的硬盘是8G,而安装Linux时采用默认分区方式的话swap分区有2G。swap分区即交换分区,类似于Windows的虚拟内存pagefile.sys。当内存不足时,把一部分硬盘空间虚拟成内存使用。而内存够用时则排不上用场。

对于实体机Linux,这2G的swap空间一般算不了什么,但对硬盘只有8G的虚拟机Linux来说,2G就很宝贵了。所以——减小Linux swap分区收回空间。

减小swap分区的方法:

1、先“df-h”和“fdisk- l”命令查看一下当前分区情况,如图。根分区为5.5G。

图中/dev/mapper/vg_"hostname"-lv_swap就是swap分区,为2G。swap分区亦可用free命令查看到。

2、用swapoff命令关闭交换分区:

# swapoff/dev/mapper/vg_"hostname"-lv_swap

然后用free命令检查下swap是否变为0了。

3、用lvreduce命令把swap分区减小1500M:

# lvreduce-L-1500M/dev/mapper/vg_"hostname"-lv_swap

输入y,确定,看到提示swap减小至516M。

4、重新把/dev/mapper/vg_"hostname"-lv_swap设置为swap分区:

# mkswap/dev/mapper/vg_"hostname"-lv_swap

5、swapon开启swap分区:

# swapon/dev/mapper/vg_"hostname"-lv_swap

然后用free命令检查下swap是否变为516M了。

扩展根分区把回收的空间利用起来

1、此时回收的1500M是闲置的自由空间,还得将它分配给根分区。还好现在的Linux分区一般是采用LVM分区方式,可以很方便地进行分区的动态扩展,不破坏现有数据。笔者这里是使用图形LVM(Logical Volume Manager)工具进行分区的动态扩展(如果没有安装此工具则需要装一下system-config-lvm的rpm包)。高手亦可在命令行下完成。

# system-config-lvm

展开“逻辑视图”->“lv_root”,点击“编辑属性”。

2、点击“使用剩余”,可以看到5.54G增大至7.0G了。然后“确定”。

3、回到LVM界面,查看到自由空间变为0了。

4、回到命令行模式用“df-h”命令检查一下,可以看到根分区增大至6.9G了。动态扩展无需重启,立即生效,大功告成!

CentOS下top和free命令查看系统中空闲内存的方法

下面介绍使用top和free命令查看系统中空闲内存

所以你执行top命令看到的

[root@linuxzgf~]# top

Mem: 8174492k total, 7124268k used,并不是代表你的应用程序已经使用了7.1的内存,这7.1G是包含了:应用程序内存+缓冲+缓存的内存的,需要用free命令查看.

下面是一个例子(单位是MB):

[root@linuxzgf~]# free-m

total used free shared buffers cached

Mem: 7982 6811 1171 0 350 5114

-/+ buffers/cache: 1346 6636

Swap: 16935 11 16924

[root@linuxzgf~]#

在这里例子中,应用程序只使用了1346MB内存,还有6636MB空闲内存可以使用.

一些简单的计算方法:

物理已用内存=实际已用内存-缓冲-缓存

= 6811M- 350M- 5114M

物理空闲内存=总物理内存-实际已用内存+缓冲+缓存

应用程序可用空闲内存=总物理内存-实际已用内存

应用程序已用内存=实际已用内存-缓冲-缓存

原始解释:转至互联网:

Linux的基本原则是没有资源应该被浪费.因此核心会使用尽可能多的RAM,来缓存来自本地和远程的文件系统的信息.系统做读写操作的时候,会将与当前运行的进程相关的数据尽量存储在RAM里.系统报告的缓存是缓冲和页缓存两者之和.缓存并不是在进程结束的时候被回收(你可能很快会启动另外一个进程,需要同样的数据),而是随需回收比如,当你启动一个需要大量内存的进程时,Linux核心会从内存中回收缓存,将得到的内存分配给新的进程.

有些区域,比如匿名内存映射(mmps)和共享内存区域,它们被报告为缓存,但不是被核心直接释放.一般的缓存不映射到进程的地址空间,仅仅是简单的核心映射,而这些特别的缓存映射到所有挂接到它们上面的进程.

cgroup 内存泄露问题排查记录

出现内存泄漏的主机为集群机器,运行时间约5天,内存使用超90%,其上运行集群管理软件和 docker并执行测试脚本反复启停容器。

长时间运行后,集群主机内存占用逐渐增加,出现应用 OOM现象。

而实际查看时发现主机内存总占用高,但应用实际占用内存低或未见显著异常。

可以看到内存占用 83.6%,而实际top显示的内存占用最高也才 0.6%没有占用内存过高的应用。

内存占用除了用户应用占用还有内核占用,遂查看内核内存占用。

使用linux文件系统接口查看

可以看到占用超高的项目为 slab内核占用:

继续查看内核详细占用,按照缓存大小进行排序

可以看到此处:

kmalloc-2048,kmalloc-4096,kernfs_node_cache,kmalloc-1024,kmalloc-192,kmalloc-512均占用较高,对比了正常主机,已经严重超过正常值。

如果是内核缓存过高则可以尝试进行内核缓存释放:

但执行上述操作后,内存占用依旧无显著下降,也符合上面看到的 SUnreclaim: 2447108 kB//slab不可回收内存大小。这部分内存不能被释放。

kmalloc为内核进行分配的内存,参考价值较大的为 kernfs_node_cache占用高,遂搜索该项是作何作用。

很明显,该现象为内核占用严重超标,于是在搜索时加入了 memory leak关键字,很快发现了该 Issues docker-run--memory slab cache leak on centos7

该 issue表示 centos7在反复运行 docker run--rm--memory 1g hello-world时存在明显的内核内存占用升高,且无法被释放。且现象和当前现象一致。

最终指向内kernel c group内存泄露问题 slab leak causing a crash when using kmem control group

大致原因是在 3.10内核上如果使用了 kmem limit参数,会导致cgroup回收时无法释放部分已分配内存。至于更深入的了解,还需要其他时间,先解决目前的问题。

原因大概确定,为了再次确定这个问题,如果能够通过上述手段复则可以确定是该问题。

在一台仅运行docker的机器上执行上述语句,查看 slab内存占用,可以看见内存占用明显上升。且最终表现和已有环境上的问题一致,总内存占用高,用户态内存占用低,内核内存占用高且无法被释放。

既然是内核问题,且知道了明确复现路径,则可以通过两种方式进行解决:

最终,进过测试后,选择了更换内核版本,将使用 Ubuntu 18.04作为新的操作系统。

Linux内核使用层次化内存管理的方法,每一层解决不同的问题,从下至上的关键部分如下:

slab是Linux操作系统的一种内存分配机制。其工作是针对一些经常分配并释放的对象,如进程描述符等,这些对象的大小一般比较小,如果直接采用伙伴系统来进行分配和释放,不仅会造成大量的内碎片,而且处理速度也太慢。而slab分配器是基于对象进行管理的,相同类型的对象归为一类(如进程描述符就是一类),每当要申请这样一个对象,slab分配器就从一个slab列表中分配一个这样大小的单元出去,而当要释放时,将其重新保存在该列表中,而不是直接返回给伙伴系统,从而避免这些内碎片。slab分配器并不丢弃已分配的对象,而是释放并把它们保存在内存中。当以后又要请求新的对象时,就可以从内存直接获取而不用重复初始化。

Slab导致的占用内存过高,Slab可以对可回收缓存手动释放,操作如下:

其中drop_caches的4个值有如下含义:

阅读剩余
THE END