linux mem overcommit

2023-11-30 12:48
文章标签 linux mem overcommit

本文主要是介绍linux mem overcommit,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 linux overcommit 机制会欺骗进程,承诺分配给他的内存空间,只有当这些page被真正touch到的时候才通过缺页机制拿到真正的物理内存。

以下摘自kernel doc

The Linux kernel supports the following overcommit handling modes0	-	Heuristic overcommit handling. Obvious overcommits ofaddress space are refused. Used for a typical system. Itensures a seriously wild allocation fails while allowingovercommit to reduce swap usage.  root is allowed to allocate slightly more memory in this mode. This is the default.1	-	Always overcommit. Appropriate for some scientificapplications. Classic example is code using sparse arraysand just relying on the virtual memory consisting almostentirely of zero pages.2	-	Don't overcommit. The total address space commitfor the system is not permitted to exceed swap + aconfigurable amount (default is 50%) of physical RAM.Depending on the amount you use, in most situationsthis means a process will not be killed while accessingpages but will receive errors on memory allocation asappropriate.Useful for applications that want to guarantee theirmemory allocations will be available in the futurewithout having to initialize every page.The overcommit policy is set via the sysctl `vm.overcommit_memory'.The overcommit amount can be set via `vm.overcommit_ratio' (percentage)
or `vm.overcommit_kbytes' (absolute value).The current overcommit limit and amount committed are viewable in
/proc/meminfo as CommitLimit and Committed_AS respectively.Gotchas
-------The C language stack growth does an implicit mremap. If you want absolute
guarantees and run close to the edge you MUST mmap your stack for the 
largest size you think you will need. For typical stack usage this does
not matter much but it's a corner case if you really really careIn mode 2 the MAP_NORESERVE flag is ignored. How It Works
------------The overcommit is based on the following rulesFor a file backed mapSHARED or READ-only	-	0 cost (the file is the map not swap)PRIVATE WRITABLE	-	size of mapping per instanceFor an anonymous or /dev/zero mapSHARED			-	size of mappingPRIVATE READ-only	-	0 cost (but of little use)PRIVATE WRITABLE	-	size of mapping per instanceAdditional accountingPages made writable copies by mmapshmfs memory drawn from the same poolStatus
------o	We account mmap memory mappings
o	We account mprotect changes in commit
o	We account mremap changes in size
o	We account brk
o	We account munmap
o	We report the commit status in /proc
o	Account and check on fork
o	Review stack handling/building on exec
o	SHMfs accounting
o	Implement actual limit enforcementTo Do
-----
o	Account ptrace pages (this is hard)
CommitLimit: Based on the overcommit ratio ('vm.overcommit_ratio'),this is the total amount of  memory currently available tobe allocated on the system. This limit is only adhered toif strict overcommit accounting is enabled (mode 2 in'vm.overcommit_memory').The CommitLimit is calculated with the following formula:CommitLimit = ([total RAM pages] - [total huge TLB pages]) *overcommit_ratio / 100 + [total swap pages]For example, on a system with 1G of physical RAM and 7Gof swap with a `vm.overcommit_ratio` of 30 it wouldyield a CommitLimit of 7.3G.For more details, see the memory overcommit documentationin vm/overcommit-accounting.
Committed_AS: The amount of memory presently allocated on the system.The committed memory is a sum of all of the memory whichhas been allocated by processes, even if it has not been"used" by them as of yet. A process which malloc()'s 1Gof memory, but only touches 300M of it will show up asusing 1G. This 1G is memory which has been "committed" toby the VM and can be used at any time by the allocatingapplication. With strict overcommit enabled on the system(mode 2 in 'vm.overcommit_memory'),allocations which wouldexceed the CommitLimit (detailed above) will not be permitted.This is useful if one needs to guarantee that processes willnot fail due to lack of memory once that memory has beensuccessfully allocated.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>int main(void)
{char *temp_malloc = NULL;uint64_t i=0;printf("wait malloc\n");sleep(10);printf("start malloc\n");temp_malloc=malloc(1024*1024*30);if(temp_malloc ==NULL){   printf("malloc fail\n");return 0;}   for(i=0; i< 1024*1024*30; i++);{   temp_malloc[i] = i&0xff;}   printf("wr done\n");sleep(100);printf("free malloc\n");free(temp_malloc);return 0;
}

 如上程序以为能分配到物理内存,可是实际上free命令结果看不到used memory增加

meminfo结果对比,申请的30M都被over committed 了,所以如上程序也没有真的touch到内存? 

 

/ # busybox pmap  2655
2655: {no such process} /mnt/mmc/sdcard/largemem
00010000       4K r-xp  /mnt/mmc/sdcard/largemem
00020000       4K r--p  /mnt/mmc/sdcard/largemem
00021000       4K rw-p  /mnt/mmc/sdcard/largemem
00022000     132K rw-p  [heap]
b50d0000   30724K rw-p    [ anon ]
b6ed1000     892K r-xp  /lib/libc-2.30.so
b6fb0000      60K ---p  /lib/libc-2.30.so
b6fbf000       8K r--p  /lib/libc-2.30.so
b6fc1000       4K rw-p  /lib/libc-2.30.so
b6fc2000      12K rw-p    [ anon ]
b6fc5000     100K r-xp  /lib/ld-2.30.so
b6feb000       8K rw-p    [ anon ]
b6fed000       4K r--p  /lib/ld-2.30.so
b6fee000       4K rw-p  /lib/ld-2.30.so
bed26000     132K rw-p  [stack]
bedd7000       4K r-xp  [sigpage]
bedd8000       4K r--p  [vvar]
bedd9000       4K r-xp  [vdso]
ffff0000       4K r-xp  [vectors]
mapped: 32108K

pmap的结果也显示出了30M的内存使用

google 查到有人用mlock 来实现防止被overcommit掉

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/mman.h>int main(void)
{char *temp_malloc = NULL;uint64_t i=0;printf("wait malloc\n");sleep(10);printf("start malloc\n");temp_malloc=malloc(1024*1024*30);if(temp_malloc ==NULL){   printf("malloc fail\n");return 0;}   if(mlock(temp_malloc, 1024*1024*30)){   printf("mlock fail\n");free(temp_malloc);return 0;}   printf("wr done\n");sleep(100);printf("free malloc\n");free(temp_malloc);return 0;
}

测试结果used 果然增加了30M

/ # freetotal         used         free       shared      buffers
Mem:        352328        42864       309464            0           40
-/+ buffers:              42824       309504
Swap:            0            0            0
/ # freestart malloc
wr donetotal         used         free       shared      buffers
Mem:        352328        73576       278752            0           40
-/+ buffers:              73536       278792
Swap:            0            0            0

至于为什么真正使用了malloc的memory也会被overcommit掉的原因,需要另开一篇认真调研下

这篇关于linux mem overcommit的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/437089

相关文章

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法

《ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法》本文介绍了Elasticsearch的基本概念,包括文档和字段、索引和映射,还详细描述了如何通过Docker... 目录1、ElasticSearch概念2、ElasticSearch、Kibana和IK分词器部署

Linux流媒体服务器部署流程

《Linux流媒体服务器部署流程》文章详细介绍了流媒体服务器的部署步骤,包括更新系统、安装依赖组件、编译安装Nginx和RTMP模块、配置Nginx和FFmpeg,以及测试流媒体服务器的搭建... 目录流媒体服务器部署部署安装1.更新系统2.安装依赖组件3.解压4.编译安装(添加RTMP和openssl模块

linux下多个硬盘划分到同一挂载点问题

《linux下多个硬盘划分到同一挂载点问题》在Linux系统中,将多个硬盘划分到同一挂载点需要通过逻辑卷管理(LVM)来实现,首先,需要将物理存储设备(如硬盘分区)创建为物理卷,然后,将这些物理卷组成... 目录linux下多个硬盘划分到同一挂载点需要明确的几个概念硬盘插上默认的是非lvm总结Linux下多

linux进程D状态的解决思路分享

《linux进程D状态的解决思路分享》在Linux系统中,进程在内核模式下等待I/O完成时会进入不间断睡眠状态(D状态),这种状态下,进程无法通过普通方式被杀死,本文通过实验模拟了这种状态,并分析了如... 目录1. 问题描述2. 问题分析3. 实验模拟3.1 使用losetup创建一个卷作为pv的磁盘3.

Linux环境变量&&进程地址空间详解

《Linux环境变量&&进程地址空间详解》本文介绍了Linux环境变量、命令行参数、进程地址空间以及Linux内核进程调度队列的相关知识,环境变量是系统运行环境的参数,命令行参数用于传递给程序的参数,... 目录一、初步认识环境变量1.1常见的环境变量1.2环境变量的基本概念二、命令行参数2.1通过命令编程

Linux之进程状态&&进程优先级详解

《Linux之进程状态&&进程优先级详解》文章介绍了操作系统中进程的状态,包括运行状态、阻塞状态和挂起状态,并详细解释了Linux下进程的具体状态及其管理,此外,文章还讨论了进程的优先级、查看和修改进... 目录一、操作系统的进程状态1.1运行状态1.2阻塞状态1.3挂起二、linux下具体的状态三、进程的

Linux编译器--gcc/g++使用方式

《Linux编译器--gcc/g++使用方式》文章主要介绍了C/C++程序的编译过程,包括预编译、编译、汇编和链接四个阶段,并详细解释了每个阶段的作用和具体操作,同时,还介绍了调试和发布版本的概念... 目录一、预编译指令1.1预处理功能1.2指令1.3问题扩展二、编译(生成汇编)三、汇编(生成二进制机器语

Rsnapshot怎么用? 基于Rsync的强大Linux备份工具使用指南

《Rsnapshot怎么用?基于Rsync的强大Linux备份工具使用指南》Rsnapshot不仅可以备份本地文件,还能通过SSH备份远程文件,接下来详细介绍如何安装、配置和使用Rsnaps... Rsnapshot 是一款开源的文件系统快照工具。它结合了 Rsync 和 SSH 的能力,可以帮助你在 li

Linux部署jar包过程

《Linux部署jar包过程》文章介绍了在Linux系统上部署Java(jar)包时需要注意的几个关键点,包括统一JDK版本、添加打包插件、修改数据库密码以及正确执行jar包的方法... 目录linux部署jar包1.统一jdk版本2.打包插件依赖3.修改密码4.执行jar包总结Linux部署jar包部署