一、引言
回答这个问题之前要考虑几个前置条件
1、操作系统是32位还是64位
2、申请完8G内存之后有没有使用
3、操作系统有没有使用Swap机制
在Linux操作系统中,32位和64位操作系统的虚拟地址的空间大小是不同的。32位系统的内核空间占1G,剩下的3G是用户空间。64位操作系统的内核空间和用户空间都是128T,分别占据内存空间的最高处和最低处,剩下的中间部分是未定义的。
二、32位系统的场景
32位操作系统,用户空间只有3G,所以进程最多只能申请3G大小的虚拟内存空间,所以申请8GB内存的话在申请虚拟内存阶段就会失败。
三、64位系统的场景
在64位操作系统下可以申请8G的虚拟内存,只有在读写虚拟内存时,操作系统才会给他分配物理内存。
没有开启swap
在64位操作系统,物理内存只有2G的实验条件下去申请128T的虚拟内存,试验后发现,进程还没申请到128T虚拟内存的时候就被杀死了,原因是触发了OOM机制,即使malloc申请的是虚拟内存,只要不去访问就不会映射到物理内存,但是还是使用到了物理内存(内核保存虚拟内存的数据结构),如果主机只有 两G的物理内存的话,大概率会触发OOM机制(给所有能杀死的进程打分,分数越高进程越容易被杀死)
开启了swap
在64位操作系统,2G物理内存的条件下,可以申请128T的虚拟内存
四、swap机制
1、什么是swap机制?
swap就是把一块磁盘空间当做内存来用,包含换入和换出两个过程。
- 换出:把进程暂时不用的磁盘数据存储到磁盘中,并释放这些数据占用的内存
- 换入:进程再次访问这些内存的时候,把他们从磁盘读到内存中来
2、swap机制的优点
可以使应用程序实际使用的内存空间远远超过系统的物理内存,磁盘的价格比内存要低,经济实惠。
3、swap机制的弊端
频繁的读写磁盘降低操作系统的运行速率
4、Linux中的swap机制触发时机
- 内存不足:当系统需要的内存超过了系统可用的内存时,内核会将不常使用的页面交换到磁盘上。这个过程是强制的直接内存回收,是同步的过程。
- 内存闲置:应用程序在启动之后大量的内存往往都不太常用,所以通过后台运行的守护进程kSwapd把这部分内存交换到磁盘上。kSwapd这个进程会在空闲内存低于一定水位时,回收内存页中的空闲内存,这个过程是异步的。相当于后台内存回收的过程。
5、swap换入换出的是什么类型的内存?
对于匿名页来讲,它们没有实际载体。而且这部分内存还可能再次被访问,所以不能直接释放内存,匿名页的回收方式是通过Linux中的swap机制,swap会把不常访问的内存先写到磁盘中,再次访问这些内存时从磁盘读入内存就可以了。
实验一:没有开启swap机制
64 位操作系统,但是物理内存只有 2 GB,而且没有 Swap 分区
申请完 4GB 虚拟内存后,通过 memset 函数访问这个虚拟内存,在访问第 2 块虚拟内存(每一块虚拟内存是 1 GB)的时候,因为超过了机器的物理内存(2GB),进程(test)被操作系统杀掉了。发生了OOM。
实验二:开启了swap机制
再有swap分区的情况下,即使物理内存大小8G小于申请并使用的内存32G,程序也可以正常运行,并没有发生OOM,但是磁盘IO会很高。有了swap分区页不意味着进程可以使用的内存是无上限的,当进程申请完64G的虚拟内存并使用到56G的时候,进程就被kill掉了,原因是系统多次尝试回收内存,还是无法满足所需使用的内存大小,进程就会被系统kill掉了,意味着发生了OOM
总结:
32位操作系统,用户空间为3G,所以直接申请8G的内存,会申请失败
64位操作系统,用户空间为128T,即使物理内存只有4G,也可以申请8G的内存,因为申请的是虚拟内存,如果这块虚拟内存被访问了,要看系统有没有swap分区:
没有swap分区:因为物理空间不够。所以进程只能被操作系统杀掉,因为发生了OOM
有swap分区:程序可以正常运行