内存管理——申请超过物理内存容量的内存 在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。 这个参数在虚拟内存的运行参数目录下,可以用 查看virtual memory运行参数,用查看参数内容 “申请的内存大于物理内存大小”这个动作称为overcommit! 虚拟内存运行参数overcommit_memory可以设定的值包括: 如果设定为 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
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/44416.html