linux申请内存失败,Linux 内存分配失败(vm.overcommit_memory的内存分配参数详解)

摘自:linux申请内存失败,Linux 内存分配失败(关于overcommit_memory)_袁廷翠09050082的博客-CSDN博客

1、问题现象和分析:

测试时发现当系统中空闲内存还有很多时,就报内存分配失败了,所有进程都报内存分配失败:

sshd@localhost:/var/log>free

total       used       free     shared    buffers     cached

Mem:      12183700    8627972    3555728          0     289252     584444

-/+ buffers/cache:    7754276    4429424

Swap:            0          0          0

sshd@localhost:/var/log>free

-bash: fork: Cannot allocate memory

sshd@localhost:/var/log>cat /proc/meminfo

-bash: fork: Cannot allocate memory

而messages日志中,也没有OOM相关的记录。最后确认原因为:/proc/sys/vm/overcommit_memory参数导致。

该环境中该参数设置为2,表示“No overcommit”,即系统中所有进程占用的虚拟内存空间不能超过上限:

cat /proc/meminfo

CommitLimit:    12061860 kB  //虚拟地址空间的上限

Committed_AS:    8625360 kB  //当前的使用量

而该参数应该默认是0,这种情况下,只有还有空闲的物理内存,就可以继续分配,不受虚拟地址空间的限制。

echo 0 > /proc/sys/vm/overcommit_memory

如此修正后解决。

摘自:linux的vm.overcommit_memory的内存分配参数详解 - zxiaocheng - 博客园

内核参数overcommit_memory 

它是 内存分配策略

可选值:0、1、2。
0, 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。

系统在为应用进程分配虚拟地址空间时,会判断当前申请的虚拟地址空间大小是否超过剩余内存大小,如果超过,则虚拟地址空间分配失败。因此,也就是如果进程本身占用的虚拟地址空间比较大或者剩余内存比较小时,fork、malloc等调用可能会失败。


1, 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。

系统在为应用进程分配虚拟地址空间时,完全不进行限制,这种情况下,避免了fork可能产生的失败,但由于malloc是先分配虚拟地址空间,而后通过异常陷入内核分配真正的物理内存,在内存不足的情况下,这相当于完全屏蔽了应用进程对系统内存状态的感知,即malloc总是能成功,一旦内存不足,会引起系统OOM杀进程,应用程序对于这种后果是无法预测的


2, 表示内核允许分配超过所有物理内存和交换空间总和的内存

则是根据系统内存状态确定了虚拟地址空间的上限,由于很多情况下,进程的虚拟地址空间占用远大小其实际占用的物理内存,这样一旦内存使用量上去以后,对于一些动态产生的进程(需要复制父进程地址空间)则很容易创建失败,如果业务过程没有过多的这种动态申请内存或者创建子进程,则影响不大,否则会产生比较大的影响

什么是Overcommit和OOM

        Linux对大部分申请内存的请求都回复"yes",以便能跑更多更大的程序。因为申请内存后,并不会马上使用内存。这种技术叫做 Overcommit。当linux发现内存不足时,会发生OOM killer(OOM=out-of-memory)。它会选择杀死一些进程(用户态进程,不是内核线程),以便释放内存。
        当oom-killer发生时,linux会选择杀死哪些进程?选择进程的函数是oom_badness函数(在mm/oom_kill.c中),该 函数会计算每个进程的点数(0~1000)。点数越高,这个进程越有可能被杀死。每个进程的点数跟oom_score_adj有关,而且 oom_score_adj可以被设置(-1000最低,1000最高)。

解决方法:

     很简单,按提示的操作(将vm.overcommit_memory 设为1)即可:

     有三种方式修改内核参数,但要有root权限:

 (1)编辑/etc/sysctl.conf ,改vm.overcommit_memory=1,然后sysctl -p使配置文件生效

 (2)sysctl vm.overcommit_memory=1

 (3)echo 1 > /proc/sys/vm/overcommit_memory

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值