最近在使用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

使用Redis时的vm.overcommit_memory内存分配控制的更多相关文章

  1. 运行时数据区即内存分配管理——JVM之六

    内存分配结构,请参考: http://iamzhongyong.iteye.com/blog/1333100

  2. JVM学习笔记三:垃圾收集器与内存分配策略

    内存回收与分配重点关注的是堆内存和方法区内存(程序计数器占用小,虚拟机栈和本地方法栈随线程有相同的生命周期). 一.判断对象是否存活? 1. 引用计数算法 优势:实现简单,效率高. 致命缺陷:无法解决 ...

  3. jvm-垃圾收集器与内存分配策略

    垃圾收集器与内存分配策略 参考: https://my.oschina.net/hosee/blog/644085 http://www.cnblogs.com/zhguang/p/Java-JVM- ...

  4. C++动态内存分配

    C++动态内存分配1.堆内存分配 :C/C++定义了4个内存区间:代码区,全局变量与静态变量区,局部变量区即栈区,动态存储区,即堆(heap)区或自由存储区(free store). 堆的概念:通常定 ...

  5. spark内存分配

    问题描述 在测试spark on yarn时,发现一些内存分配上的问题,具体如下. 在$SPARK_HOME/conf/spark-env.sh中配置如下参数: SPARK_EXECUTOR_INST ...

  6. JAVA 垃圾收集算法,垃圾收集器与内存分配策略(内容全面,解析简单易懂)

    垃圾收集器需要解决的三个问题: 1)哪些内存需要回收 2)什么时候回收 3)如何回收 背景:程序计数器,虚拟机栈,本地方法栈3个区域随线程而生,随线程而灭,在这几个区域内不需要过多的考虑回收的问题,因 ...

  7. C++ 动态内存分配(6种情况,好几个例子)

    1.堆内存分配 : C/C++定义了4个内存区间: 代码区,全局变量与静态变量区,局部变量区即栈区,动态存储区,即堆(heap)区或自由存储区(free store). 堆的概念: 通常定义变量(或对 ...

  8. [UE4]C++ 动态内存分配(6种情况,好几个例子)

    1.堆内存分配 : C/C++定义了4个内存区间: 代码区,全局变量与静态变量区,局部变量区即栈区,动态存储区,即堆(heap)区或自由存储区(free store). 堆的概念: 通常定义变量(或对 ...

  9. redis源码解析之内存管理

    zmalloc.h的内容如下: void *zmalloc(size_t size); void *zcalloc(size_t size); void *zrealloc(void *ptr, si ...

  10. 【面试必备】小伙伴栽在了JVM的内存分配策略。。。

    周末有小伙伴留言说上周面试时被问到内存分配策略的问题,但回答的不够理想,小伙伴说之前公号里看过这一块的文章的,当时看时很清楚,也知道各个策略是干嘛的,但面试时脑子里清楚,心里很明白,但嘴里就是说不清楚 ...

随机推荐

  1. Uncaught TypeError: $(...).datagrid is not a function

    项目中碰见异常"Uncaught TypeError: $(...).datagrid is not a function",网上查询基本上都是jQuery的重复引用,但是找了半天 ...

  2. 增补博客 第一篇 python 简易带参计算器

    设计一个简易的参数计算器.[输入格式]第一行输入待计算的带变量参数的计算式第二行输入各变量参数的赋值序列[输出格式]输出带变量参数的计算式的计算结果[输入样例]a+ba=1,b=10[输出样例]11 ...

  3. 字符数组数据映射转换到实体对象model注解方式 demo

    1.model对象 public class UserModel { @ColumnAnnotation(index=0) private String username; @ColumnAnnota ...

  4. 【原创】EtherCAT主站IgH解析(二)-- Linux/Windows/RTOS等多操作系统IgH EtherCAT主站移植指南

    版权声明:本文为本文为博主原创文章,转载请注明出处.如有问题,欢迎指正.博客地址:https://www.cnblogs.com/wsg1100/ 前言 目前,EtherCAT商用主站有:Aconti ...

  5. arm linux 移植 iperf3

    背景 新做的硬件需要有进行一些板级接口测试:关于网络的测试很多时候只是停留在 ping 通:能够使用就算了.不知道网络的丢包率,也不知道网络吞吐的性能. 因此,需要使用一些专业化的工具来进行测试:查阅 ...

  6. QT学习:10 IO类

    --- title: framework-cpp-qt-10-IO类 EntryName: framework-cpp-qt-10-QIODevice date: 2020-04-17 10:24:0 ...

  7. linux 4.19 ip重组

    IP重组 ip重组这部分 4.19内核与3.10内核有些差别,4.9.134以后内核中不使用低水位和工作队列了,同时使用了rhashtable 替代了 hash bucket的概念,在3.10内核中使 ...

  8. mapreduce压缩

    这是mr的一种优化策略,通过压缩编码对mapper或者reducer的输出进行压缩,以减少磁盘io,提高mr运行速度(但也相应增加了cpu运算负担) 特性: 1.mr支持将map输出的结果或者redu ...

  9. Vue2 整理(三):高级篇

    前言 基础篇链接:https://www.cnblogs.com/xiegongzi/p/15782921.html 组件化开发篇链接:https://www.cnblogs.com/xiegongz ...

  10. Spring定时任务和@Async注解异步调用

    Spring定时任务 1.@Scheduled注解方式 使用方式 @Scheduled的使用方式十分简单,首先在项目启动类添加注解@EnableScheduled. 编写定时任务方法,方法上添加注解@ ...