使用Redis时的vm.overcommit_memory内存分配控制

最近在使用Redis的时候遇到了linux系统中的vm.overcommit_memory参数设置,对此不是很了解,于是研究了一下,有了本文。

 

=====================================

 

一个尝试,如何在内存中申请空间:

>>> 100000*400000*8/1024/1024/1024
298.0232238769531

 

实际代码:

import numpy as np

x=np.zeros((100000,400000))

运行情况:

运行上面的代码后执行top命令,发现该进程的内存空间并没有明显变大,可以说x变量申请的298G空间并没有被分配,那么如何使内存真正被分配呢,给出下面的代码:

import numpy as np

x=np.zeros((100000,400000))

x+=0.0001

运行情况:

该代码的执行可以通过top命令发现确实有298G的内存空间被分配。

 

从上面的这个操作可以知道,在linux系统中系统真正的分配内存并不是在你申请的时候,而是在你初始化的时候。比如你使用C语言中的malloc申请内存,但是此时你所获得的是操作系统分配给你的虚拟地址,而此时这部分内存并没有真正的分配给你,要理解这个操作就需要对操作系统的虚拟地址和真实地址有一定的了解。

 

关于overcommit_memory与linux内存分配参考:

https://blog.51cto.com/u_13875041/5877796

https://zhuanlan.zhihu.com/p/551677956

 

 

overcommit方式进行内存分配,就是允许内核分配的内存空间大于实际物理内存空间,如果使用overcommit方式分配内存后实际初始化后的内存空间大于物理内存那么就会进行(OOM = out-of-memory)报错,并对某个进程进行kill,以达到释放物理内存的目的。

个人认为overcommit方式的内存分配和航空公司的机票超售是相像的,航空公司对航班机票的销售往往都会超过实际机舱座位数的,其目的就是大概率会有一部分人买了机票后由于各种原因无法登记,因此可以利用该种情况来进行一票多售实现收益最大化,然而该种方式也有一定概率遇到问题,那就是售出的机票所有的顾客都全部到达机场候机,比如150个座位的航班,卖了160张票,结果真遇到了160人全部到达机场候机的情况,这时就需要按照某种方式将多余的10个人安排到其他航班上。

可以说overcommit方式进行内存分配是linux系统放弃掉一定的系统稳定性来实现性能最大化的一种方式;为防止完全不受限制的overcommit方式造成linux系统不稳定的问题,一般使用受限制的overcommit方式进行内存分配,也就是下文中所提到的vm.overcommit_memory=0的情况;但是对于一些科学计算问题,或者Redis服务器,这样使用场景比较单一,但是对内存需求比较大,同时往往很多时候虽然申请的内存空间较大但是实际初始化的内存只是其中一部分的情况,此时我们一般设置vm.overcommit_memory=1,也就是完全不受限制的overcommit内存分配方式。

 

 

linux中​ vm.overcommit_memory​ 参数的设置:

分别可以取值为: 0,1,2

取0时,使用Heuristic算法进行内存的overcommit分配;

取1时,对申请的内存进行不受限制的overcommit分配;

取2时,不允许overcommit。

 

举例:(这里不考虑使用linux系统中的swap,因此这里说的内存即为物理内存)

如果vm.overcommit_memory设置为2,那么物理内存为64G,所有进程申请的内存总和上限即为64G。

如果vm.overcommit_memory设置为1,那么物理内存为64G,所有进程申请的内存总和不受限制,比如所以进程申请的内存总额为128G,但是这里需要注意的是内存初始化后的总和不能超过物理内存的64G;也就是说,这种设置下只要最终的进程申请的内存初始化不超过物理总内存,那么是可以随意申请任何大小的内存空间的;

(还是上面最早提到的知识点,linux系统中内存申请和内存实际分配是两件事,如果进程申请内存后并没有进行初始化,那么这块内存空间并没有从实际的物理内存中分配出去)

 

在实际的linux系统运行中,vm.overcommit_memory参数一般默认为0,也就是使用heuristic算法对内存进行申请分配。

------------------------------------------------------------------

 

https://zhuanlan.zhihu.com/p/551677956中给出了heuristic算法的描述:

 

Heuristic overcommit算法在以下函数中实现,基本上可以这么理解:
单次申请的内存大小不能超过 【free memory + free swap + pagecache的大小 + SLAB中可回收的部分】,否则本次申请就会失败。

 

------------------------------------------------------------------

 
 
也就是说,heuristic算法虽然允许使用overcommit,但是是一种受限制的overcommit,该种方式主要限制单次申请的overcommit内存不要过大。heuristic方式在分配内存时,虽然允许overcommit,但是在分配内存时要考虑整体的可用内存空间+可调配页的内存空间+可回收的内存空间的大小,这样的话虽然内存分配时存在overcommit,但是如果在初始化时内存空间不够也可以通过内存的调配及回收来进行一定程度上的缓解,因此在实际的linux服务器运行过程中,我们一般设置 vm.overcommit_memory=1 。

 

 

-----------------------------------------------------------------------

 

查询linux系统的overcommit设置:

cat /proc/sys/vm/overcommit_memory

 

 

===============================================

 

参考:

https://blog.csdn.net/weixin_42073629/article/details/117170686

 

posted on   Angry_Panda  阅读(1038)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
历史上的今天:
2019-07-01 【转载】 小样本学习-元学习

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示