一道面试题关于malloc的面试题 【Linux从基础到进阶】

我提出的一个小问题

让我们先看一个小问题,
观察下面代码,当malloc一块空间后,没有释放,这块空间会被泄露吗?

    char * s = (char * )malloc(1024);
    exit(0);
  1. 当这个进程不是一直运行的进程时,它不会被泄露,因为当这个进程结束后,该进程的空间都会被释放(假如说这个都会造成内存泄漏的话,那么操作系统的健壮性也太差了吧)
  2. 当该进程是一直运行的进程,如挂载在服务器上的 ,那么它将在运行中造成内存泄漏,直至把空间耗尽。

第一道题

这是32位的(内存只有2G)的rad hat 的内存图,而且现在已经有其他进程占用了一部分空间了
在这里插入图片描述
让我们运行这个代码,它将申请2G空间,大家猜猜能不能申请成功?
在这里插入图片描述

运行之后,查看内存状态,我们发现申请成功了
我们可以看出,当内存快到达2G时,有一部分内存被挤压到虚拟内存去了
在这里插入图片描述

第二道题

还是在上面的32位内存为2G的rad hat 上运行这个程序,当我们运行下面的代码时,此时我们要申请3G的空间,我们上次也看到,物理内存与虚拟内存之和为4G,远远大于3G,此时能不能成功?
在这里插入图片描述
当我们执行时,发现成功不了
在这里插入图片描述
那这个是为什么呐?

这个也和虚拟内存有关

简单介绍一下虚拟内存

Linux:

 为了屏蔽I/O的差异,操作系统提供了虚拟文件系统(VFS)
 为了屏蔽内存和I/O的差异,操作系统提供了虚拟存储器(虚拟内存)
 为了屏蔽CPU 内存和I/O,也为了方便调动资源,操作系统提供了进程这一概念
 为了安全性,同时为了使多进程环境下,使得进程之间的内存地址不受影响,于是
 提供了虚拟内存中一概念

那虚拟内存的空间有多大呐?

虚拟内存大小和CPU的位数有关

CPU 在 ALU这个算数逻辑单元中运算数据
所以CPU 的位数指的是ALU的宽度,也就是数据总线的个数

CPU位数数据总线地址总线
8位816
16位1620
32位3232

n位CPU,虚拟空间的大小就为2^n次方。
对于上面的32位系统来说,虚拟空间的大小为4G。

32位系统虚拟内存分布图

在这里插入图片描述

在引入虚拟内存前,当一个程序想要运行时,它首先要能被加载在内存(内存的大小要足够)中

下面的图的物理内存的大小装不下这个程序,所以不能运行。
在这里插入图片描述
而当我们有了虚拟内存后,我们就可以把磁盘当作内存(虚拟成内存)来用,在运行程序时,把程序的一部分存储到内存中,一部分存储到磁盘中
在这里插入图片描述

而当我们需要使用页面4时,我们便从磁盘中把4加载到内存中,把好长时间没用的页面(比如说7)替换掉,把7放到磁盘中

因为对于32位系统来说,虚拟内存只有4G,而虚拟内存又分为内核区用户区,内核区为1G,而用户区只为3G,所以当要malloc时,申请的空间必须小于3G,因为栈等其他东西也要占用内存。

所以当问分配空间够不够时?

我们不只能只关注内存,还要考虑到虚拟内存,而当考虑虚拟内存时,还要考虑到用户空间。

这样的话,我在学这里的时候突然有一个问题

根据上面我们所知的,只要我们的磁盘能把程序全部装载进去,不管内存多的大小,,当执行的时候,我们只需要从磁盘把程序全部加载到内存中去,这样的话,只要磁盘有多大,那么虚拟内存就可以有多大

但是我之后就想清楚了,因为内存,L1,L2,L3 ,三级缓存,这些东西,本来存在的目的就是为了减少CPU和磁盘速度的差异,如果说按我上面想的那样的话,这样内存存在的意义就没有了。

在这里插入图片描述

简单介绍一下malloc的过程

当我们不malloc时,堆那里啥空间都没有,当我们执行一次malloc时(要求分配字节比较小),然后会初始化堆(堆那里便会划分100多k的空间)然后,划分好字节块,比如说划分上好多个16个字节的,32个字节的,64个字节的,128个字节的,比如说你要60个字节的,就给你64个字节的块,当用户free之后,便会把字节块归还到这里(并不是归还给系统),然后说随着用户的使用,这里的字节块不够了,那么堆便继续扩展
假如说用户要划分1个G,那么便不从这里的空闲块区划分了,而是直接在堆区上划分1个G,然后给用户

在这里插入图片描述

我们来打个比方,假如说堆比作卖水的小卖部,假如学校里面一直没有人买水,小卖部这里肯定也没有屯水,因为没有这种需求,而有一天有一个人要提出买水,突然有了需求,小卖部这里就开始备几件水,当然肯定不能备好几十件吧,因为一直从来没有人买过水,而今天这种买水的需求是突然的,假如说有一天,学校要开运动会,有一个人突然要买一百件水,一到小卖部,发现不够呀,然后小卖部老师直接联系批发商,直接让批发商送给那个人。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值