首页 > 数据库 >使用Redis时的vm.overcommit_memory内存分配控制

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

时间:2023-07-10 13:32:51浏览次数:35  
标签:overcommit linux Redis 内存空间 vm 内存 memory 分配

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

 

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

 

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

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

 

实际代码:

import numpy as np
x=np.zeros((100000,400000))

运行情况:

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

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

import numpy as np
x=np.zeros((100000,400000))
x+=0.0001

运行情况:

使用Redis时的vm.overcommit_memory内存分配控制_杂谈_02

该代码的执行可以通过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

使用Redis时的vm.overcommit_memory内存分配控制_杂谈_03

 

 

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


 

标签:overcommit,linux,Redis,内存空间,vm,内存,memory,分配
From: https://blog.51cto.com/u_15642578/6675582

相关文章

  • 粒子群算法PSO优化LSSVM最小二乘支持向量机惩罚参数c和核函数参数g,用于回归预测,有例子
    粒子群算法PSO优化LSSVM最小二乘支持向量机惩罚参数c和核函数参数g,用于回归预测,有例子,易上手,简单粗暴,直接替换数据即可。仅适应于windows系统。质量保证,完美运行。这段程序主要是一个基于粒子群优化算法(ParticleSwarmOptimization,PSO)的支持向量机(SupportVectorMachine,SVM)......
  • JVM 面试题
    JVM面试题JVM是JavaVirtualMachine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。JVM屏蔽了与......
  • Linux LVM的基本使用
    LinuxLVM的基本使用LVM介绍LVM(LogicalVolumeManager),即逻辑卷管理,是Linux环境下对磁盘分区进行管理的一种机制,LVM是建立在硬盘和分区之上的一个逻辑层,来提高磁盘分区管理的灵活性。通过LVM系统管理员可以轻松管理磁盘分区,如:将若干个磁盘分区连接为一个整块的卷组(volumegroup),......
  • 基于redis的分布式锁
     1为什么要使用分布式锁的理解分布式架构图:例1:在电商业务采用分布式架构后,程序部署在3个tomcat容器中(1个tomcat容器代表一个服务器,3个tomcat可理解在北京上海深圳都有部署电商服务),成员变量A代表商品数量。在北京的Alice,上海的Bob,深圳的Tom,都分别发起了购买或取消iPhone12......
  • Java虚拟机(JVM):第四幕:自动内存管理 - 经典垃圾收集器
    前言:如果说收集算法是内存回收的方法论,那么垃圾收集器则是内存回收的实践者。整哥Java堆:FullGC。1、Serial收集器:最基础、历史最悠久的收集器,这是一个单线程工作的收集器。2、ParNew收集器:是Serial收集器的多线程并行版本,可以说是跟Serial完全一样。CMS收集......
  • JVM系列---【Arthas的下载与使用】
    Arthas的下载与使用使用jdk自带的工具,一般需要开通一些端口,添加一些jvm启动参数,比较麻烦,生产环境一般也不让重启,所以我们现在用Arthas更方便。调优的目的主要为了减少GC,因为每次GC都会调用STW机制(stoptheworld),而STW会停掉用户线程,因此频繁触发STW就会给用户感觉网站很卡。尤......
  • Redis 面试要点
    一、Redis主从服务器和集群服务器区别? 1)架构不同:Redis集群采用分布式储存模式,多节点同时提供读写服务,可横向扩展;   而Redis主从只有一个master节点,多个slave节点,只有master节点提供读写服务;2)数据完整性:Redis集群中如果任何一个节点故障,其它节点可以正常提供服务,保......
  • lvm命令
    定义LVM(LogicalVolumeManager,逻辑卷管理)本质上是一个虚拟设备驱动,是在内核中块设备和物理设备之间添加的一个新的抽象层次。使用LVM主要是方便管理、增加了系统的扩展性,重点在于可以动态调整文件系统的容量!常用术语1.物理存储介质(hephysicalmediaThephysicalmedia):指系统......
  • spring-data-redis2.3.9不支持redis6.2提供的GEOSEARCH命令
    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><exclusions><exclusion><groupId>io.lettuce</groupId>......
  • Redis事务和持久化机制
    Redis031Redis事务Redis通过multi、exec、watch等命令实现事务功能。Redis的事务功能相对较弱,无法和关系型数据库的事务相媲美。1.1multi和exec命令语法:multi开始事务命令1命令2...exec 执行事务示例:127.0.0.1:6379>multi //开始事务OK127......