【Linux内核】内存管理——申请超过物理内存容量的内存

转载请注明: https://www.cnblogs.com/Ethan-Code/p/16627754.html

在4G主存机器申请8G内存会发生什么

  • 在 32 位操作系统,因为进程最大只能申请 3 GB 大小的虚拟内存,所以直接申请 8G 内存,会申请失败。
  • 在 64 位操作系统,因为进程最大可以申请 128 TB 大小的虚拟内存,即使物理内存只有 4GB,申请 8G 内存也是没问题,因为申请的内存是虚拟内存。如果这块虚拟内存被访问了,要看系统有没有 Swap 分区:
    • 如果没有 Swap 分区,因为物理空间不够,进程会被OOM机制杀掉
    • 如果有 Swap 分区,即使物理内存只有 4GB,程序也能正常使用 8GB 的内存,进程可以正常运行

问题的关键

通过上述结论可以看出,当malloc申请的内存大小超过机器物理内存容量大小时,结果由两个关键要素决定:

  • 虚拟内存空间大小
  • swap机制

进程能够访问到的地址范围由虚拟地址空间大小决定,如果申请的内存大小超过这个范围,则会直接申请失败,连虚拟内存都没有分配。

如果申请的内存大小在虚拟内存范围内,则不管物理内存大小剩多少,总是能够申请成功。只不过申请的内存是虚拟内存,只有进程访问这些虚拟内存时才会使用物理内存建立映射。

如果系统没有swap分区,当物理内存使用完后,因为申请的虚拟内存比物理内存大,继续访问后续的虚拟内存时,由于物理内存没有足够的空闲页框可以使用,内核会触发OOM机制将占用内存最大的进程杀掉

如果系统有swap分区,则当物理内存不足时,根据LRU算法,把最近最少使用的页面暂时换出磁盘里面,腾出物理内存建立新的映射,等到再次访问的时候再从磁盘中换入物理内存。因此当申请的内存比物理内存大得多时,会不断执行页面的换入换出,从而保证了进程的运行,但是相应的会影响性能,是一种时间换空间的机制。

更深层的分析

其实,上面提到的第一个关键要素虚拟内存空间大小,严格来说并不是说申请的内存大小在虚拟内存范围内就能申请成功。

实际上,当申请的内存大于物理内存大小时,能不能申请成功还受到一个内核参数影响——overcommit_memory

这个参数在虚拟内存的运行参数目录下,可以用 ls /proc/sys/vm查看virtual memory运行参数,用cat /proc/sys/vm/overcommit_memory查看参数内容

“申请的内存大于物理内存大小”这个动作称为overcommit

虚拟内存运行参数overcommit_memory可以设定的值包括:

#define OVERCOMMIT_GUESS  0
#define OVERCOMMIT_ALWAYS 1
#define OVERCOMMIT_NEVER  2
  • 如果设定为 OVERCOMMIT_ALWAYS,表示永远允许 overcommit 这个动作。
  • 如果设定为 OVERCOMMIT_NEVER ,表示系统不允许 overcommit 这个动作。
  • 如果设定为 OVERCOMMIT_GUESS ,表示让内核根据当前的内存情况进行判断。

默认情况下,overcommit_memory的值设定为 OVERCOMMIT_ALWAYS,因此才会有“总是允许申请的内存超过物理内存大小”的结论。

如果是 OVERCOMMIT_NEVER 的话会有一个判断overcommit上限的标准,只要超过上限就申请失败。

另外一个 OVERCOMMIT_GUESS 情况就比较复杂,需要收集内存信息:

  • 系统的free page frame
  • 用户空间进程读写文件造成的page cache使用的page frame
  • 进程间的share memory机制造成的shmem page frame
  • swap分区上空闲的page frame
  • slab对象的reclaim page
  • 能让系统运行需要预留的totalreserve_pages的page frame
  • admin_reserve_kbytes的free page

然后对这些内存信息进行计算,最后比对本次申请virtual memory的page数目和当前计算出来的free数据,如果在保留了足够的page frame之后,还有足够的page可以满足本次分配,那么就批准本次vm的分配。

具体可以参考文末引用文章↓


好文推荐:http://www.wowotech.net/memory_management/overcommit.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值